#include一个奇怪的二级指针int main(void) { int arr[5] = { 1,2,3,4,5 }; int(*p)[5] = &arr; printf("%pn", p); //运行后会发现这二者数值上相等 printf("%pn", *p); return 0; }
#include一个奇怪的解释int main(void) { int arr[5] = { 1,2,3,4,5 }; int(*p)[5] = &arr; //程序成功运行,且结果都为:1 printf("%dn", **p); //我们可以知道p=&arr printf("%dn", **&arr); //二者都是二级指针 return 0; }
奇怪问题的某个解释
指向数组的指针,设计者为了和指向元素的指针区分开来做了这样的设计:单纯的数组名就表示一个指向数组首元素的指针,其需要开辟一个单独的空间存放,同时数组名空间内的值不可变。如果要表示整个数组的地址的话,就在单纯的数组名之上,提高了一下等级,变为二级指针,但不单独给空间。
设计一个规则,当对数组名取地址,就是对一级指针取地址。需要一个变量存放它,需要一块空间,这样就是一个正常的二级指针,但在这里不单独给空间,就把数组名(一级指针)占的空间作为它的空间,同时提高它的等级,变为二级指针,给这种指针标记(特殊的二级指针),搞出一个类型来标记/表示它:type(*)[]。如果要对这种二级指针进行解引用时,就只降低它的等级,变为正常的一级指针
//这些只是假设,为了解决*p=p的问题参考资料想出的一个可以说服自己的解释。理解后可以不管这些,将这个作为一种新的类型去理解即可。一个值为和一级相同的指针类型,不过加了一个二级指针的特性。依旧需要分配空间(也可以和数组一样理解空间分配,将&arr传递过去之后,系统根据类型分配了一块空间)。
总结:数组名是一个指针常量,&数组名就是是对一级指针取地址,一个二级指针,但赋给了它一个特殊规则。
一些正常的应用按照我的理解,&arr是一个特殊的二级指针,类型为type(*)[ ]。
#includeint main(void) { int arr[5] = { 1,2,3,4,5 }; int(*p)[5]; //定义一个该类型指针变量 p= &arr; //把该类型的值给它 printf("%dn",(*p)[1]); //*p使其变为普通一级指针:arr printf("%dn", arr[1]); //arr:指向数组首元素的指针 printf("%dn", *(*p + 1)); printf("%dn", *(*(&arr) + 1)); //p=&arr printf("%dn", *(arr + 1)); //*p=arr printf("%dn", arr[1]); //结果均为:2 //这样是不是就好理解多了 return 0; }



