首页 > 解决方案 > 这两段代码有何不同?

问题描述

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

1.)

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

输出 - 12

2.)

int i;
    for(i++; i++; i++){
        if(i>10)    break;
    }
    printf("%d",i);

输出 - 1

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

标签: c++cloopsfor-loop

解决方案


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

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

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

另请参阅这些相关问题:

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

另请参阅这些课堂笔记中的第 4.2 节第 4.3 节

另请参阅C FAQ 列表中的问题 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
}

编译器会发出哪些可能的操作序列,使其计算出最终值 1?”

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

这个答案又是,“未初始化的局部变量会导致未定义的行为。未定义的行为意味着任何事情都可能发生。”

这个答案的重要之处在于它说“任何事情都可能发生”,而“任何事情”绝对意味着任何事情。这绝对没有意义。

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

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

因为允许编译器做任何事情,它可能会发出代码,就好像你的程序已经编写好了,例如,

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

“但这没有任何意义!”,你说。“编译器怎么能把“ for(i++; i++; i++) ...”变成“ i++”?答案——你听说过,但也许你还是不太相信——当一个程序包含未定义的行为时,编译器被允许做任何事


推荐阅读