# 指针数组 根据[数组的定义](https://mengkang.net/1008.html):同一类型多个元素的集合,所以数组也能存放指针集合。 ```c #include <stdio.h> int main(int argc, char const *argv[]) { int a = 1; int b = 2; int *p[2] = {&a, &b}; printf("a : %p,%d\n", &a, *(&a)); printf("*(p + 0) : %p,%d\n", *(p + 0), *(*(p + 0))); printf("b : %p,%d\n", &b, *(&b)); printf("*(p + 1) : %p,%d\n", *(p + 1), *(*(p + 1))); return 0; } ``` 输出结果 ``` a : 0x7fff55e0ca7c,1 *(p + 0) : 0x7fff55e0ca7c,1 b : 0x7fff55e0ca78,2 *(p + 1) : 0x7fff55e0ca78,2 ``` 上例子,`p`表示数组,`int *`表示该数组存放的`int`类型的指针。依然数组指针偏移1位,是下一个成员的值。这一点和原来规则一致 https://mengkang.net/1009.html#blog-title-3 不变。 # 数组指针 ## 指向二维数组的指针 数组指针,指的是数组名的指针,即数组首元素地址的指针。(因为数组名就代表数组的首地址) 上面的例子关于`int *p[2]`的定义也可以写成`int* p[2]`,或者`int * p[2]`,但是不能写成`int (*p)[2]`。 因为在语法分析的时候`*`符号是和左边的数据类型结合的,不管中间有多少空格。而使用`()`之后,则使得`p`变成一个数组指针。 ```c #include <stdio.h> int main(int argc, char const *argv[]) { int arr[2][2] = {{1,2},{3,4}}; int (*p)[2] = arr; // p是一个指针变量,它指向一个数组,而这个数组的每个成员又是一个含有2个int的数组 printf("%d\n", *(*(p+0)+0));//1 printf("%d\n", **p);//1 printf("%d\n", *(*(p+1)+1));//4 return 0; } ``` 这就是 ```c int *p[2] int (*p)[2] ``` 的区别 ## 指向一维数组的指针 前面为了对比,先说了指向二维数组的指针,显得非常绕。一维数组的指针呢,就非常简单了。 ```c #include <stdio.h> int main(int argc, char const *argv[]) { int a[5], *pa; for (int i = 0; i < 5; i++) { a[i] = i; } pa = a; for (int i = 0; i < 5; i++) { printf("a[%d]=%d\n", i, *pa); pa++; } } ```