C语言指针退化问题

HarderHeng Lv5

数组指针

考虑以下的代码。

1
2
3
4
5
6
7
8
#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

接下来考虑以下的代码。

1
2
3
4
5
6
7
8
9
#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位系统下)。

数组传递参数

1
2
3
4
5
6
7
8
9
10
11
12
#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,这种情况实际传递了常量指针,就不会发生指针退化。

  • Title: C语言指针退化问题
  • Author: HarderHeng
  • Created at : 2024-11-27 10:19:57
  • Updated at : 2024-12-17 09:32:06
  • Link: https://harderheng.life/2024/11/27/C语言指针退化问题/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments