new*_*low 4 c variables stack for-loop automatic-storage
我的产品代码类似于以下内容.据我说,输出是'0 1 2 3'.但类似代码的输出是'1 1 1 1'.
for(i = 0 ;i < 5;i++){
int j;
if(i)
printf("%d ",j);
j = i;
}
Run Code Online (Sandbox Code Playgroud)
我的理解是,在'for'循环的整个周期期间,j仅在堆栈上分配一次,并且在迭代期间使用相同的值.另外,如果我将j的声明移到for循环中,我会得到预期的结果.我在这里错过了什么?
PS - 当我在我的个人计算机上运行相同的代码时,我得到了预期的输出.但在生产方面却有所不同.
首先,为了清楚自动局部变量的存储持续时间,让我引用C11标准,章节§6.2.4,(强调我的)
声明标识符没有链接且没有存储类说明符的对象
static具有自动存储持续时间,[...]
和,
对于没有可变长度数组类型的此类对象,其生命周期从entry进入与其关联的块,直到该块的执行以任何方式结束.(输入一个封闭的块或调用一个函数暂停,但不会结束,执行当前块.)如果以递归方式输入块,则每次都会创建一个新的对象实例.对象的初始值是不确定的.
所以,在你的代码中,每次迭代得到一个新的实例中j.什么都没有保留.
在你的代码中,
int j; //not initialized
if(i)
printf("%d ",j); //this one here
Run Code Online (Sandbox Code Playgroud)
您正在尝试使用j具有不确定值的单元化自动局部变量.它调用未定义的行为.
根据C11章节§6.7.9
如果未显式初始化具有自动存储持续时间的对象,则其值不确定
和相关的,对于UB,附件§J.2
具有自动存储持续时间的对象的值在不确定时使用.
一旦你的代码命中UB,无论如何都无法证明输出是合理的.
OTOH,当你j在循环外声明时,它有函数范围.然后,与上述情况不同,循环的所有迭代将只有一个实例j.
根据执行流程,第一次,i为0,if将评估为false,printf()将被跳过并将j初始化.然后,在下一次迭代中,当你点击时printf(),会j被初始化,之后一切都很顺利.