跳转至

第十二章 指针和数组


指针和数组

当指针指向数组元素时,它可以操作数组元素。此时,可以对指针进行算术运算(加、减、比较)。

数组名即是指向数组中第一个元素的指针。

指针的算术运算

指针指向了数组元素,之后对这个指针做算术运算就是合法的操作。但不要越界。

  • 指针加、减整数,代表移动元素指向

  • 指针相减,代表指针指向元素之间的距离

  • 指针比较,比较的是指针指向元素谁前谁后

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个。