C语言传参及指针疑问:数组元素修改、返回地址与警告差异解析
C语言值传递与数组参数的疑问解析
先看你给出的代码和运行结果:
#include <stdio.h> int *fun(int x,int y, int c[]){ c[0]=100; x=887; return &c[0]; } int main() { int x=10,y=20,*z; int c[]={1,2,3,4,5}; z=fun(x,y,c); printf("%d\n",*z); printf("%d\n",c[0]); printf("%d\n",x); return 0; }
运行输出:
100
100
10
下面逐个解释你的疑问:
1. 为什么main里的x没被修改,但c[0]被修改了?
- 对于
int x参数:C语言的值传递是把实参的数值复制一份给函数形参,函数内操作的x是独立的局部副本,和main里的x分属两块不同内存。所以函数里把x改成887,只会修改这个副本,完全不影响main里的原变量。 - 对于
int c[]参数:C语言中数组作为函数参数时,会自动退化成指向首元素的指针,也就是函数里的c实际等价于int *c,传递的是main数组c的首元素地址。函数里c[0]=100是通过地址直接修改main数组的内存,自然会改变原数组的值。
2. 为什么返回&c[0]无警告,返回&x则出现警告?
- 返回
&c[0]时,这里的c指向的是main函数定义的数组,该数组的生命周期覆盖整个main函数的执行过程。fun执行完毕返回时,main仍在运行,数组内存还未被销毁,返回的地址是有效的,因此编译器不会发出警告。 - 返回
&x时,这里的x是fun函数的局部变量,它的内存分配在fun的栈帧上。当fun执行结束,栈帧会被销毁,x的内存被释放,返回它的地址会得到一个野指针(指向已释放的无效内存),编译器能检测到这个风险,所以会抛出警告。
内容的提问来源于stack exchange,提问作者Cblue X
相关产品推荐
相关产品推荐

