C语言中的指针数组和数组指针(新手必看)
在 C 语言中,指针数组和数组指针的结构如下图所示:

图 1 指针数组和数组指针的结构
指针数组是数组,数组的全部元素都是指针,如
数组指针只有一个指针,指向某数组,即“指向数组的指针”,如
为便于理解和记忆,可在中间加上“的”字,即分别是“指针的数组”和“数组的指针”。
在 p1 的声明“int *p1[10]”中,由于“[ ]”的优先级比“*”要高,因此 p1 先与“[ ]”结合,构成一个数组,数组名为 p1,
由此可见,p1 是一个数组,其包含 10 个指向 int 型数据的指针,即指针数组。
执行 p1+1 时,p1 指向下一个数组元素,
如要将二维数组赋给一维指针数组,代码如下:
运行该语句后,输出 p1[i] 值后,发现其值差 16 个字节,因为每个整数占 4 个字节,而 p1[i] 指向一个一维、有 4 个整型数据的数组。
至于 p2 的声明“int (*p2)[10]”,由于“( )”的优先级比“[ ]”高,因此“*”号和 p2 构成一个指针,指针变量名为 p2;int 和 [ ] 修饰的是一个数组,数组在这里并没有名字,是个匿名数组。
由此可见,p2 是一个指针,它指向一个包含 10 个 int 型数据的数组,即某数组的指针,指向一个存储 10 个 int 型数据的数组首地址。
p1 和 p2 相同之处是存储的都是指针或地址。不同之处是 p1 的 10 个元素均指向整型变量,是存储指针的数组;p2 是一个指针,它指向的是整型数组。
如要将二维数组赋给一维指针,则应这样赋值:

图 1 指针数组和数组指针的结构
指针数组是数组,数组的全部元素都是指针,如
int *p1[10]
。数组指针只有一个指针,指向某数组,即“指向数组的指针”,如
int (*p2)[10]
。为便于理解和记忆,可在中间加上“的”字,即分别是“指针的数组”和“数组的指针”。
在 p1 的声明“int *p1[10]”中,由于“[ ]”的优先级比“*”要高,因此 p1 先与“[ ]”结合,构成一个数组,数组名为 p1,
int *
修饰的是数组的内容,即数组中的每个元素。由此可见,p1 是一个数组,其包含 10 个指向 int 型数据的指针,即指针数组。
执行 p1+1 时,p1 指向下一个数组元素,
p1=a
这样赋值是错误的,因为 p1 是数组首地址,是常量,只存在 p1[0]、p1[1]、p1[2]……p1[9],而且它们都是指针变量,可以用来存放变量地址。但可以这样 *p1=a
(加 * 号变成取值),这里 *p1 表示指针数组第一个元素的值,a 是数组首地址的值。具体代码如下:
int a[10]; int *p1[10]; *p1=&a[0]; //或*p1=a;或p1[0]=a; printf("最终的目标字符串: %d\n",*p1);
如要将二维数组赋给一维指针数组,代码如下:
int *p1[3]; int a[3][4]; for(int i=0;i<3;i++) { p1[i]=a[i]; printf("%d ",p[i]); }这里 int *p1[3] 表示一个一维数组内存放着 3 个指针变量,分别是 p1[0]、p1[1]、p1[2],所以要分别赋值。
运行该语句后,输出 p1[i] 值后,发现其值差 16 个字节,因为每个整数占 4 个字节,而 p1[i] 指向一个一维、有 4 个整型数据的数组。
至于 p2 的声明“int (*p2)[10]”,由于“( )”的优先级比“[ ]”高,因此“*”号和 p2 构成一个指针,指针变量名为 p2;int 和 [ ] 修饰的是一个数组,数组在这里并没有名字,是个匿名数组。
由此可见,p2 是一个指针,它指向一个包含 10 个 int 型数据的数组,即某数组的指针,指向一个存储 10 个 int 型数据的数组首地址。
p1 和 p2 相同之处是存储的都是指针或地址。不同之处是 p1 的 10 个元素均指向整型变量,是存储指针的数组;p2 是一个指针,它指向的是整型数组。
如要将二维数组赋给一维指针,则应这样赋值:
int a[3][4]; int (*p2)[4]; //该语句是定义一个数组指针,指向含4个元素的一维数组 p2=a; //将该二维数组的首地址赋给p2,也就是a[0]或&a[0][0] p2++; //该语句执行过后,也就是p2=p2+1;p2跨过行a[0]指向了行a[1]