第十二章 指针和数组
指针和数组
当指针指向数组元素时,它可以操作数组元素。此时,可以对指针进行算术运算(加、减、比较)。
数组名即是指向数组中第一个元素的指针。
指针的算术运算
指针指向了数组元素,之后对这个指针做算术运算就是合法的操作。但不要越界。
-
指针加、减整数,代表移动元素指向
-
指针相减,代表指针指向元素之间的距离
-
指针比较,比较的是指针指向元素谁前谁后
Warning
不能相加两个指针。
指针用于数组处理
指针可以操作数组中的元素,比如遍历数组:
int *p = 0;
for (p = &a[0]; p < &a[N]; ++p)
{
// ...
}
这里N是数组a的长度,虽然a[N]
不存在,但对它取地址是合法且安全的操作。
使用*和++组合
如,*p++
++操作的优先级高于*,所以这样的组合操作,会先操作指针p,然后获取其指向的内容。
后置++会先返回p,然后对p递增,可以用这个操作遍历数组:
int *p = &a[0];
while (p < &a[LEN])
{
int n = *p++;
// ...
}
用数组名作为指针
数组名即第一个元素的地址。即a与&a[0]等价。
数组名是一个指针常量,不能改变其值,应该把它赋值给一个指针变量。
因此可以这样遍历数组:
int *p = 0;
for (p = a; p < a + LEN; ++p)
{
// ...
}
指针和多维数组
二维数组在内存中实际上是一维的连续存储的。其首元素如果这样写:
-
&a[0]
,代表第一行的首地址 -
&a[0][0]
,代表第一个元素的首地址
这俩地址的值是一样的,但意义不同,因为其指向元素的类型不一样。前者是int*
,后者是int
。
多维数组名作为指针
int a[n][m]
这样的二维数组,其数组名a代表的是a[0]
的地址,a[i]
得到的是第i行的地址。
这样的指针类型是:
int (*p)[m] = a;
或
typedef int (*Line)[m];
Line p = a;
这里定义了一个指向数组的指针,这个数组的元素有m个。