假设我有一个主要功能如下:
void main()
{ int *p;
p = foo(31);
printf(“%d”, (*p)+2);
bar(7); /* Body of function bar() not shown */
printf(“%d”, (*p)+4);
}
int *foo(int x)
{
return &x;
}
假设函数bar()正确编译,如果bar()的主体没有写入其传入的参数空间,为什么printf的第二个结果 11 。
更具体地说,我的问题是为什么 bar()的 7 的传入参数值会替换值 31 ?
更重要的是,当main函数将值31传递给foo()时,值31如何通过?通过注册?或者编译器创建一个临时变量来传递31?为什么 foo()和 bar()的传入参数在内存中共享相同的位置
答案 0 :(得分:5)
函数参数是其局部变量。所以在这个函数定义中
int *foo(int x)
{
return &x;
}
返回一个指向局部变量的指针。
结果该程序有未定义的行为。
您可以通过以下方式设想函数定义及其调用
p = foo(31);
int *foo( /* int x */ )
{
int x = 31;
return &x;
}
退出函数后,变量x
将不会处于活动状态。因此,指针具有无效值,该值是不指向实际对象的值。为函数foo
的参数分配的内存可以通过调用其他函数来覆盖,例如通过调用函数printf
..
考虑到根据C标准,不带参数的函数main
应声明为
int main( void )
和函数foo
应在使用前声明。否则,编译器可以发出一条消息,表明使用了不兼容的类型,或者找不到相应的函数。
答案 1 :(得分:1)
函数foo在其局部变量x中接收输入参数值的副本。 foo看到的并不取决于函数的参数是否恒定。
vatiable x位于堆栈上,当foo返回时释放。所以foo将地址返回到堆栈中的某个位置。返回指向局部变量的指针是对各种问题的邀请。
在这种情况下,调用bar时,相同位置最有可能被重用。