Skip to content

C语言指针退化问题

· 3 min

数组指针#

考虑以下的代码。

#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。

不会指针退化的情况#

即只要传递的是数组名这个常量指针本身,就不会发生退化,如果传递的是一个普通指针,其值等于数组的首地址,并不能和数组名这个常量指针等价。

所以如果传递的是常量指针的地址,比如&arr,这种情况实际传递了常量指针,就不会发生指针退化。