这两段代码有何不同?

-5 c c++ loops for-loop

我尝试了这些代码行,发现令人震惊的输出。我期待一些与初始化相关的原因,无论是一般还是for循环。

1.)

int i = 0;
    for(i++; i++; i++){
        if(i>10)    break;
    }
    printf("%d",i);
Run Code Online (Sandbox Code Playgroud)

输出-12

2.)

int i;
    for(i++; i++; i++){
        if(i>10)    break;
    }
    printf("%d",i);
Run Code Online (Sandbox Code Playgroud)

输出-1

我希望语句“ int i = 0”和“ int i”相同。它们之间有什么区别?

Ste*_*mit 5

我希望语句“ int i = 0”和“ int i”相同。

不,那是您的错误期望。如果将变量声明为函数之外的变量(作为“全局”变量),或者使用static关键字声明了该变量,则即使您不编写,也可以保证将其初始化为0 = 0。但是在函数内部定义的变量(不带的普通“局部”变量static没有这种保证的初始化。如果您未明确初始化它们,则它们将开始包含不确定的值。

(但是请注意,在这种情况下,“不确定”并不意味着“随机”。如果编写使用或打印未初始化变量的程序,则通常会发现,每次运行该程序时,它都包含相同的值在大多数机器上,发生的情况是该变量采用了先前调用的函数在堆栈上留下的任何值。)

另请参阅以下相关问题:

非静态变量初始化
静态变量初始化?

另请参见4.2节第4.3节这些课堂笔记

另请参阅“ C常见问题解答”列表中的问题1.30


附录:根据您的评论,听起来好像是您初始化失败时i,它刚开始时的不确定值是0,所以现在的问题是:

“给出程序

#include <stdio.h>
int main()
{
    int i;                   // note uninitialized
    printf("%d\n", i);       // prints 0
    for(i++; i++; i++){
        if(i>10)    break;
    }
    printf("%d\n", i);       // prints 1
}
Run Code Online (Sandbox Code Playgroud)

编译器可能发出什么可能的操作序列,导致编译器计算最终值1?”

这可能是一个很难回答的问题。在这个问题的其他答案和评论中,有好几个人试图回答这个问题,但是由于某些原因,您没有接受该答案。

再次给出的答案是:“未初始化的局部变量会导致未定义的行为。未定义的行为意味着可能发生任何事情。”

关于这个答案的重要一点是它说“任何事情都可能发生”,而“任何事情”绝对意味着任何事情。绝对没有必要。

正如我所说的那样,第二个问题甚至没有任何意义,因为它包含一个内在的矛盾,因为它询问“编译器可能发出什么样的操作序列”,但是由于程序包含未定义的行为,因此编译器甚至没有义务发出合理的操作序列。

如果您真的想知道编译器发出的操作顺序,则必须询问它。在Unix / Linux下,使用-S标志进行编译。在其他编译器下,我不知道如何查看汇编语言输出。但是请不要指望输出有任何意义,也请不要让我向您解释(因为我已经知道它没有任何意义)。

由于允许编译器执行任何操作,因此它可能会发出代码,就好像您的程序已被编写一样,例如,

#include <stdio.h>
int main()
{
    int i;                   // note uninitialized
    printf("%d\n", i);       // prints 0
    i++;
    printf("%d\n", i);       // prints 1
}
Run Code Online (Sandbox Code Playgroud)

您说:“但这没有任何意义!” “编译器如何将“ for(i++; i++; i++) ...”变成只是“ i++”?答案-您已经听说过,但也许您仍然不太相信-是,当程序包含未定义的行为时,允许编译器执行以下操作:做任何事情