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