c++ - 这两段代码有何不同?
问题描述
我尝试了这些代码行并发现了令人震惊的输出。我期待一些与初始化相关的原因,无论是在一般情况下还是在 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”是相同的。它们之间有什么区别?
解决方案
我希望语句“int i = 0”和“int i”是相同的。
不,那是你的错误期望。如果变量在函数外部声明(作为“全局”变量),或者使用static
关键字声明,即使不写= 0
. 但是在函数内部定义的变量(没有 的普通“局部”变量static
)没有这种保证初始化。如果您没有显式初始化它们,它们开始包含不确定的值。
(但请注意,在这种情况下,“不确定”并不意味着“随机”。如果您编写的程序使用或打印未初始化的变量,通常您会发现每次运行时它都包含相同的值程序。碰巧,它甚至可能是 0。在大多数机器上,发生的情况是变量采用之前调用的函数“在堆栈上”留下的任何值。)
另请参阅这些相关问题:
附录:根据您的评论,听起来当您初始化失败时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++
”?答案——你听说过,但也许你还是不太相信——当一个程序包含未定义的行为时,编译器被允许做任何事。
推荐阅读
- c - 如何在多线程中使用 memory_buffer_alloc_init()?
- c++ - 使用 CMake find_package() 时无法打开源文件“GL/glew.h”
- suffix-tree - 为什么这个字符串的后缀树中这两个节点之间没有后缀链接?
- javascript - 在我的网站上实现服务器和客户端的 2FA
- sql-server - SQL Express 2019 远程访问不起作用
- python - 使用 self._variable 从其他函数调用变量,为什么它似乎工作而不是随机工作(一定有原因)?
- node.js - 如何让 npm 包 json-server 与 API Routes 一起运行
- python - 如何在python列表中进行嵌套循环
- python - 自动调整 QLabel 的大小以适应更新的 QTableWidget 跨度
- graphviz - Graphviz 不需要的子图节点分离拉伸