数组指针#
考虑以下的代码。
#include<stdio.h>
int main(){ char a[] = {'h', 'e', 'l', 'l', 'o','\n'}; printf("%d\n",sizeof(a)); return 0;
}定义了一个内容为hello的字符串,此时使用sizeof传入的a本质上是是一个数组指针,它即指向整个字符串,也指向字符串的第一个元素,在同一个域内调用sizeof,会将数组信息传递给sizeof,所以输出结果为字符串的长度6。
即,一个数组的名字,即是指向第一个元素的指针(pointer to the first element),也能代表一整个数组(the pointer to the array)。
指针退化#
在上面的代码中显然sizeof将a视为是代表一整个数组的指针,所以返回大小为6。
接下来考虑以下的代码。
#include<stdio.h>
int main(){ char a[] = {'h', 'e', 'l', 'l', 'o','\n'}; char *p = a; printf("%d\n",sizeof(p)); return 0;
}这段代码中创建了一个char类型的p指针,将a的值传递给p,最后的输出结果为4。
此时sizeof会将p认为是一个单纯的指针,不会传递数组的信息进去,也就是说不能够知道后面的数组有多长,最后返回的值也就是指针的长度4(32位系统下)。
数组传递参数#
#include<stdio.h>
int size(char a[]){ return sizeof(a);}
int main(){ char a[] = {'h', 'e', 'l', 'l', 'o','\n'}; printf("%d\n",size(a)); return 0;
}在这里给数组传参,将数组传参进去,本质上还是传递了一个指针进去,数组指针经过传参退化成了普通指针,所以得到的值为4。
不会指针退化的情况#
- 直接使用sizeof最原始数组名进行求值,可以得到数组的长度。
- 对数组名进行取地址操作,即得到一个指向数组的指针,对这个指针进行操作则不会出现指针退化。
即只要传递的是数组名这个常量指针本身,就不会发生退化,如果传递的是一个普通指针,其值等于数组的首地址,并不能和数组名这个常量指针等价。
所以如果传递的是常量指针的地址,比如&arr,这种情况实际传递了常量指针,就不会发生指针退化。