1 2 3 4 5 6 7 8 9 10 11 12 | int a[10]; int *b; int (*c)[10]; int d; int e[10][2]; int (*f)[2]; b = a; b = &a[0]; c = &a; d = a[2]; f = e; |
直接使用数组,等价于取数组首元素的地址。a等价于&a[0]。
1 2 3 4 5 6 7 8 9 10 11 | #include <stdio.h> int main( int argc, char **argv) { char * array[2] = { "One" , "Two" }; char * (*p)[2] = &array; printf ( "%p %p\n" , p, *p); printf ( "%s\n" , p[0][1]); return 0; } |
输出
1 2 3 | $ . /a .out 0x7ffebd12aa20 0x7ffebd12aa20 Two |
array和&array的值是一样的都是数组的地址。相反的,p和*p也是一样的,也是数组的地址。这里可能让人比较蒙。
另外要读取数组的的元素,需要使用p[0][n],这种方式,不能使用p[n]。但是如果转换成2级指针,那么就是可以的,这只是编译的解释不同而已:
1 2 | char **p2 = array; printf ( "%s\n" , p2[0]); |
如上输出One。
*,如果是标量类型,比如int *,那么*ptr,取的是标量的值,如指向内存区域的int的值。
如果指向的是数组,比如上述的p,那么*p,取的是数组的地址。这就是p变量存储的地址,而不是去解释该地址处的内容。因此*运算的结果,依赖于指针的类型。
对数组取*,则等价取的是数组的第一个元素,如上述*array等价于array[0]。
参考:
https://stackoverflow.com/questions/381542/with-arrays-why-is-it-the-case-that-a5-5a
https://stackoverflow.com/questions/1641957/is-an-array-name-a-pointer#