指针数组与数组指针---傻傻分不清楚?

简介: 整形数组是存放整形的数组字符数组是存放字符的数组所以,指针数组是存放指针(地址)的数组整形数组的书写形式是int arr[10],字符指针书写形式是char arr[10],所以字符指针的书写形式是int *arr[10] char* arr[10]接下来创建一个字符指针数组

1.指针数组


什么是指针数组呢?

我们通过以前学过的数组进行类比:


整形数组是存放整形的数组

字符数组是存放字符的数组

所以,指针数组是存放指针(地址)的数组

整形数组的书写形式是int arr[10],字符指针书写形式是char arr[10],所以字符指针的书写形式是int *arr[10] char* arr[10]

接下来创建一个字符指针数组


int main()
{
  char a = 'a';
  char b = 'b';
  char c = 'c';
  char d = 'd';
  char* arr[4] = {&a,&b,&c,&d};
  return 0;
}


创建了四个char类型变量,将他们取地址放到字符指针数组里,这是最基本的应用


还可以将字符串放到字符指针数组里,字符指针可以存放一个一个字符串中第一个字符的地址,所以这里是将4个字符串首字符的地址存到字符指针数组里


int main()
{
  char str1[] = "hello";
  char str2[] = "world";
  char str3[] = "byebye";
  char str4[] = "world";
  char* arr[4] = {str1,str2,str3,str4};
  return 0;
}



4df3bf01f36342c6be08f245d29b5736.png

还可以用一维指针数组模拟二维数组


#include <stdio.h>
int main()
{
  int arr1[5] = { 1,2,3,4,5 };
  int arr2[5] = { 2,3,4,5,6 };
  int arr3[5] = { 3,4,5,6,7 };
  int arr4[5] = { 5,6,7,8,9 };
  int arr5[5] = { 0,1,0,2,0 };
  int* arr[5] = { arr1,arr2,arr3,arr4 ,arr5};
  for (int i = 0; i < 5; i++)
  {
  for (int j = 0; j < 5; j++)
  {
    printf("%d ", *(*(arr + i) + j));
  }
  printf("\n");
  }
  return 0;
}




前面说过,对于一个指针p , *(p+i)与p[i]等价

所以上述程序中的*(*(arr + i) + j)也可以写成arr[i][j],也就是如二维数组一样的写法

这个指针数组的结构:


2d29311df478412ca56d172971787326.png

2.数组指针


对于数组指针,还是类比其他类型指针


整形指针是一个指向整形变量的指针

字符变量是一个指向字符变量的指针

所以数组变量就是一个指向数组的指针

整形指针的类型是int*,字符指针的类型是char*,所以数组指针的类型就是int(*)[10]

char ch = 'w';
char *pc = &ch;
int num = 10;
int* pi = &num;
int arr[10];
int(*pa)[10] = &arr;


在这个整形数组指针,*先与pa结合:(*pa),所以int(*pa)[10]是一个指针


在这里赋给数组指针的是数组名取地址,那么数组名和数组名取地址有什么区别呢?请点击跳转另一篇文章:数组与地址,数组名到底是什么?


数组指针到底怎么用呢?


之前如果要输出一个整形数组,我们可以使用指针,这里的指针通常是数组元素首地址


但是如果非要用数组指针输出数组中的元素也是可以的


int main()
{
  int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
  int(*p)[10] = &arr;
  for (int i = 0; i < 10; i++)
  {
  printf("%d ", (*p)[i]);
  }
  return 0;
}


这里的p是一个数组指针,先将解引用*p,得到数组,然后通过下标访问(*p)[i])就可以得到数组元素了


但是这样做是很别扭的,不如直接用整形指针输出


其实 数组指针在一位数组中用的不多,在二维数组中会用到


在以往的对于二维数组的传参,定义函数时,在参数列表中最简单的写法是直接以二维数组的形式传形参


void print(int arr[3][4], int x, int y) //直接以二维数组的形式写是最简单的
{
  for (int i = 0; i < x; i++)
  {
  for (int j = 0; j < y; j++)
  {
    printf("%d ", arr[i][j]);
  }
  printf("\n");
  }
}
int main()
{
  int arr[10] = { {1,2,3,4},{2,3,4,5},{3,4,5,6} };
  print(arr, 3, 4);
}



但是,对于一位数组int arr[10],如果在函数中想要接受它,不但可以以数组的形式接受,用一个一级指针接受也是可以的



void printf(int arr[10],int len)  //可以用数组的形式接收
{
  ;
}
void printf(int *arr,int len) //也可以用指针的形式接收
{
  ;
}
int main()
{
  int arr[10] = { 1,2,3,4,5,6,7,8,9,10};
  print(arr,10);
}


如果也想要用一个指针变量去接收二维数组传参就略有不同了


函数实参传一个二维数组名过去,数组名是数组首元素地址,所以二维数组数组名就是一个一维数组的地址,这个二维数组名其实就是一个数组指针,所以在函数中要用一个数组指针去接收


void print(int(*arr)[4],int x,int y)  //用一个数组指针去接收
{
  for (int i = 0; i < x; i++)
  {
  for (int j = 0; j < y;j++)
  {
    printf("%d ", (*(arr+i))[j]);
  }
  printf("\n");
  }
}
int main()
{
  int arr[3][4] = { {1,2,3,4},{2,3,4,5},{3,4,5,6} };
  print(arr, 3, 4);
}



16

学过了数组指针和指针数组,看看下面这些都是什么?


int arr[5];
int *parr1[10];
int (*parr2)[10];
int (*parr3[10])[5];


int arr[5],是一个长度为5的整形数组

int *parr1[10],是一个整形指针数组,长度为10,里面存放整形指针

int (*parr2)[10],是一个数组指针,parr2指向一个长度为10的整形指针

int (*parr3[10])[5],这个比较复杂,一步一步分析,首先看名称parr3先与[10]结合,所以这是一个数组,长度为10,然后剩下int(*)[5],所以在数组parr3中存放的是类型为int(*)[5]的数组指针,它指向一个长度为5的整形数组。


目录
相关文章
|
1月前
使用指针访问数组元素
【10月更文挑战第30天】使用指针访问数组元素。
36 3
|
19天前
|
存储 程序员 编译器
C 语言数组与指针的深度剖析与应用
在C语言中,数组与指针是核心概念,二者既独立又紧密相连。数组是在连续内存中存储相同类型数据的结构,而指针则存储内存地址,二者结合可在数据处理、函数传参等方面发挥巨大作用。掌握它们的特性和关系,对于优化程序性能、灵活处理数据结构至关重要。
|
23天前
|
存储 C语言 计算机视觉
在C语言中指针数组和数组指针在动态内存分配中的应用
在C语言中,指针数组和数组指针均可用于动态内存分配。指针数组是数组的每个元素都是指针,可用于指向多个动态分配的内存块;数组指针则指向一个数组,可动态分配和管理大型数据结构。两者结合使用,灵活高效地管理内存。
|
23天前
|
容器
在使用指针数组进行动态内存分配时,如何避免内存泄漏
在使用指针数组进行动态内存分配时,避免内存泄漏的关键在于确保每个分配的内存块都能被正确释放。具体做法包括:1. 分配后立即检查是否成功;2. 使用完成后及时释放内存;3. 避免重复释放同一内存地址;4. 尽量使用智能指针或容器类管理内存。
|
23天前
|
存储 NoSQL 编译器
C 语言中指针数组与数组指针的辨析与应用
在C语言中,指针数组和数组指针是两个容易混淆但用途不同的概念。指针数组是一个数组,其元素是指针类型;而数组指针是指向数组的指针。两者在声明、使用及内存布局上各有特点,正确理解它们有助于更高效地编程。
|
26天前
|
存储 人工智能 算法
数据结构实验之C 语言的函数数组指针结构体知识
本实验旨在复习C语言中的函数、数组、指针、结构体与共用体等核心概念,并通过具体编程任务加深理解。任务包括输出100以内所有素数、逆序排列一维数组、查找二维数组中的鞍点、利用指针输出二维数组元素,以及使用结构体和共用体处理教师与学生信息。每个任务不仅强化了基本语法的应用,还涉及到了算法逻辑的设计与优化。实验结果显示,学生能够有效掌握并运用这些知识完成指定任务。
48 4
|
1月前
使用指针访问数组元素
【10月更文挑战第31天】使用指针访问数组元素。
42 2
|
1月前
|
算法 索引
单链表题+数组题(快慢指针和左右指针)
单链表题+数组题(快慢指针和左右指针)
39 1
|
2月前
|
存储
如何使用指针数组来实现动态二维数组
指针数组可以用来实现动态二维数组。首先,定义一个指向指针的指针变量,并使用 `malloc` 为它分配内存,然后为每个子数组分配内存。通过这种方式,可以灵活地创建和管理不同大小的二维数组。
|
2月前
|
存储
如何通过指针数组来实现二维数组?
介绍了二维数组和指针数组的概念及其区别,详细讲解了如何使用指针数组模拟二维数组,包括定义与分配内存、访问和赋值元素、以及正确释放内存的步骤,适用于需要动态处理二维数据的场景。