# 指针数组
根据[数组的定义](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++;
}
}
```