MMM*_*VII 0 c arrays pointers dereference
码:
int arr[5] = {1,2,3,4,5};
int (*p)[5] = &arr;
printf("p:%p\n",p);
printf("*p:%p\n",*p);
Run Code Online (Sandbox Code Playgroud)
结果:p = *p = arr = 0x7ffee517c830它们是数组的所有地址

p用于访问arr [i] 的正确方法是*(*p+i)
指针的类型p是int(*)[5],所以p指向一个类型为的数组int [5].但我们不能说p指向一个看不见的外壳arr,p毕竟是一个变量.它存储地址arr,也是arr[0]第一个元素的地址arr.
我以为*p会得到我1,这是第一个元素arr.
取消引用操作意味着将值p作为地址获取并从该地址获取值.对?因此P存储的地址arr,也就是0x7ffee517c830在这里,并1存储在该地址.不**p违法吗?第一个取消引用给我们1,第二个取消引用将1用作非法的地址.
我错过了什么?
结果*p是数组类型的左值表达式.使用(*p)是完全一样的使用arr中你现在能想到的任何表达.
例如:
&*p 手段 &arr**p意思是*arr(合法的).(*p)[i]手段arr[i].sizeof *p手段sizeof arr.在这方面,阵列并不特别.你可以看到同样的现象int x; int *q = &x;.现在*q,x具有完全相同的含义.
关于你的最后一段,我认为通过将指针想象成美化的整数,你会让自己感到困惑.有些人用这种方式教指针,但IMO并不是一种好的教学技巧,因为它会让你现在感到困惑.
如果你取消引用,int(*)[5]你会得到一个,int[5]而这就是它的全部.数据类型在解除引用时很重要.谈论"解除引用0x7ffee517c830" 是没有意义的.同样,这并不是数组所特有的; 如果你取消引用a char ***,你会得到一个char **等等
在这个讨论中数组"不同"的唯一方法是,如果你尝试对它们进行算术运算,或者输出它们等,会发生什么int[5].例如,如果你提供一个printf参数,那么就会隐式转换为int *指向这5个中的第一个.将*操作符应用于a 时也会发生这种转换int[5],这就是为什么你会得到一个int.