7.1 数组指针
数组指针 的意思,即为通过 指针 引用 数组,例如int (*p)[10],此时 p 是一个 指针变量 ,指向一个数组大小为 10 的 数组,所以int (*p)[10]即为一个数组指针。
二维数组与数组指针的关系
-
在我们对指针进行加法(减法)运算时,它前进(后退)的步长与它指向的数据类型有关
-
p指向的数据类型是int[4],那么p+1就前进4×4=16个字节,p-1就后退16个字节,这正好是数组a所包含的每个一维数组的长度。
-
也就是说p+1会使得指针指向二维数组的下一行,p-1会使得指针指向数组的上一行。
-
-
数组名a在表达式中也会被转换为和p等价的指针。
下面我们使用指针 p 来访问二维数组中的每个元素,按照上面的定义:
-
p 指向数组a的开头,也即第0行;p+1前进一行,指向第1行。
-
*(p+1) 表示取地址上的数据,也就是整个第1行数据。注意是一行数据,是多个数据,不是第1行中的第0个元素,下面的输出结果证明了这一点:
#include<stdio.h> int main(){ int a[3][4] = {{0,1,2,3},{4,5,6,7},{8,9,10,11}}; int(*p)[4]=a; printf("%d\\n",sizeof(*(p+1))); return0; } 输出结果: 16 -
* ( p+1)+1 表示第1行第1个元素的地址。*(p+1)单独使用时表示的是第1行数据,放在表达式中会被转换为第1行数据的首地址,也就是第1行第0个元素的地址,因为使用整行数据没有实际的含义,编译器遇到这种情况都会转换为指向该行第0个元素的指针;就像一维数组的名字,在定义时或者和sizeof、&一起使用时才表示整个数组,出现在表达式中就会被转换为指向数组第0个元素的指针。
-
*( * ( p+1 ) + 1 ) 表示第1行第1个元素的值。很明显,增加一个*表示取地址上的数据。
可以简单导出以下的等价关系:
a+i == p+i
a[i] == p[i] == * ( a+i ) == * ( p+i )
a[i] [j] == p[i] [j] == * ( a [i]+j)== * ( p[ i ] +j) == * ( * (a+i)+j)== * ( * (p+i)+j)
7.2 指针数组
由于运算符优先级[]的优先级大于*,若定义为int *p[10],此时该定义为一个大小为10、用来存放指针的数组,即为指针数组。
7.3 数组指针与指针数组的区别
指针数组和二维数组指针在定义时非常相似,只是括号的位置不同:
int *(p1[5]);//指针数组,可以去掉括号直接写作 int *p1[5];
int (*p2)[5];//二维数组指针,不能去掉括号
指针数组和二维数组指针有着本质上的区别:指针数组是一个数组,只是每个元素保存的都是指针,以上面的p1为例,在32位环境下它占用4×5=20个字节的内存。二维数组指针是一个指针,它指向一个二维数组,以上面的p2为例,它占用4个字节的内存。

789

被折叠的 条评论
为什么被折叠?



