我很难理解这两个源代码的打印值.
#include<stdio.h>
void a(void){
int a;
a++;
printf("%d\n",a);
}
int main(void){
a();
a();
a();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
为什么这个代码打印出"1 2 3",而第二个代码:
#include<stdio.h>
void a(void){
int a;
a++;
printf("%d\n",a);
}
int main(void){
int b;
printf("%d\n",b);
a();
a();
a();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
打印出:"0,垃圾值,相同的垃圾值+1,相同的垃圾值+2".
主函数(或任何其他函数)中的任何未初始化对象是否应该被赋予随机(垃圾)值?
更新:我觉得解释"变量是未初始化的,所以他们可以从其他程序获得任何剩余的值 - > UB"是不够的.我可以复制粘贴相同的源代码100次,仍然得到打印值0.我使用的是gcc 4.4.3.
未初始化的自动变量的值是不确定的,因此如果您没有在具有特定标志集的特定计算机上讨论特定编译器,那么它实际上是不可预测的.即使你谈论一个非常具体的平台和设置,你仍然可能无法获得可重现的结果.
在某些非常具体的情况下,您可以进行预测,演示文稿Deep C将对此进行总体讨论,并介绍幻灯片的具体情况71.
在现代系统中,自动变量通常会在堆栈上分配,您可能会得到相同的内存位置,因此您会看到三个连续的值.但是你不应该依赖这种行为,使用未初始化的变量是未定义的行为,结果是不可预测的.
在C99标准草案告诉我们在第6.7.8 初始化第10的是:
如果未显式初始化具有自动存储持续时间的对象,则其值不确定.
并在以下定义中告诉我们indeterminate value:
要么是未指定的值,要么是陷阱表示
更新
什么是未定义的行为?在最严格的意义上,它是C标准没有强加要求的行为,它是标准的构造.它在标准草案的章节中定义3.4.3:
使用不可移植或错误的程序结构或错误数据时的行为,本国际标准不对此要求
并有以下说明:
可能的未定义行为包括完全忽略具有不可预测结果的情况,在转换或程序执行期间以环境特征(有或没有发出诊断消息)的特定文档执行,终止翻译或执行(发布时)一条诊断信息).
在一天结束时,它是设计一种有效语言和一种安全语言之间的权衡,这是从每个C程序员应该知道的关于未定义行为#1/3的内容中解释的.
以下是更好地理解未定义行为的更多链接: