Appearance
c
int arr[5] = {1,2,3,4,5};
int *p1 = arr;
int (*p2)[5] = &arr;在上面的代码中, p1 就是数组本身的别名, 它和 arr 基本等价.
与 arr 不一样的地方是,它们的类型不一样,前者类型是
int[5]而后者是int*,用sizeof运算结果不一样。
但 p2 则是这个数组的指针, 它保存的地址指向的是整个数组本身.
最明显的一个区别是, p1 偏移的时候移动一个 int 单位, 而 p2 偏移的时候则完整地偏移一个长度为 5 的 int 数组的长度.
取出数组数据的时候, p1 使用 p1[0] , 和数组一样; p2 使用 (*p2)[0] , 因为 p2 是数组的指针, 它保存数组的地址 ( 说白了就是指针的指针 ) , 所以用 * 运算符, 可以取出数组, 然后再用数组的方法去取数值.
在 C语言指针与二维数组 中遇到过 , 没有办法指向每一行的问题 , 现在可以用数组指针来解决 :
c
int arr[3][4] = {{1,2,3,4}, {5,6,7,8},{9,9,9,9}};
int (*p)[4] = arr;这次不会报类型不匹配的警告, 避免隐式转换带来的误解 .
c
int arr[3][4] = {{1,2,3,4}, {5,6,7,8},{9,9,9,9}};
int (*p)[4] = arr;
int *q = arr; // 有隐式转换, 会警告, 正确做法是 int *q = arr[0];
printf("%d\n", p[1][2]); // 7
printf("%d\n", q[1]); // 2从上面可以看到 , 数组指针和一般指针在声明上的区别.
如果声明的时候长度和指向的数组不匹配会怎么样?
同样地, 也是报一个类型不匹配的警告, 并通过了编译 :
bash
test2.c:7:19: warning: initialization of ‘int (*)[2]’ from incompatible pointer type ‘int (*)[4]’ [-Wincompatible-pointer-types]
7 | int (*p)[2] = arr;
| ^~~这说明 int (*)[4] 是类型的名称, 其中的数字也不能少.
而运行的结果也产生了错误.