以下是代码:
#include <stdio.h>
int *addition(int a, int b);
int result;
int *result_ptr;
int *addition(int a, int b)
{
int c = a + b;
int *d = &c;
return d;
}
int main(void)
{
result = *(addition(1,2));
result_ptr = addition(1,2);
printf("result = %d\n", result); //outputline1
printf("result_ptr = %d\n", *result_ptr); //outputline2
return 0;
}
如果在编写当前代码时对其进行编译和处理,则result_ptr会给出奇怪的值。但是,如果您交换2个输出线,则不会。为什么这样做?
答案 0 :(得分:2)
您将返回局部变量c
的地址。这是undefined behavior。也就是说,您的程序是错误的,这意味着它没有义务显示可预测或理智的行为。改变两个printf
的位置会给你另一个错误的程序,这个程序(再次)不需要与之前的错误程序正确或连贯地运行。
编辑(添加C99标准草案N1256的相关引文 - 强调我的)
6.5.3.2地址和间接运算符
[...]
<强>语义强>
一元*运算符表示间接。如果操作数指向函数,则结果为 功能指示符;如果它指向一个对象,结果是一个左值指定 宾语。如果操作数的类型为''指向类型'',则结果的类型为''type''。 如果是 已经为指针分配了无效值,一元*运算符的行为是 未定义。的 87)
(脚注#87)
因此,
&*E
相当于E
(即使E
是空指针),&(E1[E2])
相当于((E1)+(E2))
。如果E是函数指示符或左值是一元&
运算符的有效操作数,则总是如此,*&E
是函数指示符或等于E
的左值。如果*P
是左值并且T
是对象指针类型的名称,则*(T)P
是左值,其类型与T
指向的类型兼容。由一元
*
运算符取消引用指针的无效值中有一个空指针,一个地址与指向的对象类型不一致, 和后面的对象地址它的生命周期结束。
相关句子是最后一个句子(强调我的):c
局部变量已经结束了它的生命周期,当它的addition
函数返回的地址被取消引用时main
。