跳到主要内容

C 指针数组和数组指针

1. 基本概念

  • 指针数组是数组,每个数组元素里面都会存放一个指针变量。
  • 数组指针是指针,它指向的是一个数组。

2. 指针数组

int *p1[5];  // 这是一个指针数组

从符号优先级可以进行分析:数组下标 [ ] 的优先级是要比取值运算符 * 的优先级高的,p1会被先定义成具有5个元素的数组,然后它的数据类型会是 **int ***,所以它们应该是指向整型变量的指针。ZYepwK.png

所以指针数组是一个数组,每个数组元素里面都会存放一个指针变量。也就是存放着地址。

/* 指针数组演示 */
#include <stdio.h>

int main(int argc, char *argv[])
{
int a[5] = {1, 2, 3, 4 , 5};
int *p1[5];
int i;

for(i=0; i<5; i++)
{
p1[i] = &a[i];
printf("%p\t%d\n", p1[i], *p1[i]);
}

return 0;
}

3. 数组指针

int (*p2)[5]; // 这是一个数组指针

从符号优先级可以进行分析:数组下标 [ ] 和圆括号位于同一个优先级队列,结合性从左往右看,所以 p2 先被定义成了一个指针变量,后面则是一个具有5个元素的数组,所以指针变量 p2 就是指向一个具有5个元素的数组,由于指针变量的类型就是它所指向的类型,所以 int 就是定义数组元素的类型为整型。

ZYeQ41.png

所以数组指针是一个指针,它指向的是一个数组。

/* 数组指针演示 */
#include <stdio.h>

int main(int argc, char *argv[])
{
int a[5] = {1, 2, 3, 4, 5};
int (*pa)[5] = &a;// *pa == a
int i;

for(i=0; i<5; i++)
{
printf("%d\t", (*pa)[i]); // printf("%d\t", a[i]);
}
printf("\n");

return 0;
}

4. 二维数组和数组指针

#include <stdio.h>

int main()
{
int a[3][4] = { // *(*(a+3)+4)
{0, 1, 2, 3},
{4, 5, 6, 7},
{8, 9, 10, 11}};
int (*pa)[4];
int i, j;

pa = a;
for (i = 0; i < 3; i++)
{
for (j = 0; j < 4; j++)
{
printf("%2d ", *(*(pa+i)+j));
}
printf("\n");
}

return 0;
}

pa 是一个指向数组的指针,这个数组包含了 4 个元素,所以 pa 的跨度是 4 * sizeof(int),然后把二维数组第一个元素的地址赋值给 pa。这时,pa+1 恰好是二维数组一行的跨度。对 pa+1 进行解引用,得到的就是二维数组第二行第一个元素的首地址。所以我们可以通过数组指针的方式来访问二维数组。