c - 简单的 C 程序,奇怪的输出
问题描述
在这个简单的 C 程序中,当我评论Line Y
并Line X
保持原样时,对输出的调用的f()
输出0
并Line B
输出一些随机数。当我评论Line X
和取消评论时Line Y
,输出是一个随机数,因为是Line B
另一个随机数,因为Line Y
。但是,当我评论Line A
和时Line B
,都调用f()
output 0
。有人可以向我解释为什么会这样吗?先感谢您。顺便说一句,我在gcc
没有任何标志的情况下使用它并在 macOS Catalina 上运行它。
#include <stdio.h>
void f() {
int x;
printf("%d\n", x);
}
int main() {
f(); // Line X
int a; // Line A
printf("%d\n", a); // Line B
f(); // Line Y
return 0;
}
解决方案
当你这样做时:
int x;
printf("%d\n", x);
您正在为堆栈分配空间x
,然后打印其值。该值理论上可以是任何值(您不能期望它为零或任何特定值),但实际上它将是之前发生在堆栈上的任何值。
这就是为什么更改周围的代码会更改 的值x
,因为堆栈被程序的其他部分使用,并且更改这些部分会在堆栈中x
恰好被分配的那个空间中留下不同的值。
x
当您更改编译器选项或使用不同的计算机时,您也可能会得到不同的值。
您可能想知道为什么删除“Line A”会改变“Line A”之前的“Line X”的输出。这是因为编译器可能会main
在函数的开头而不是逐行进行所有堆栈分配(例如,它为a
before分配空间x
,从而改变您在 print 时看到的值x
,因为它已经“向下”移动了一个堆栈上的空间)。
推荐阅读
- python - Pandas df 根据整数索引列表重新排序行和列
- mysql - 如何在mysql中找到每列的值数与主键的比率?
- angular - CSP 阻止来自 S3 的图像
- odoo - Odoo 用户和管理员在同一个组
- azure - 激活 RBAC 和 AAD 集成后,如何授予服务主体对 AKS API 的访问权限?
- spring - 异常:rg.springframework.cloud.gcp.data.datastore.core.mapping.DatastoreDataException:无法将类 PageRequest 转换为 Datastore
- elasticsearch - ElasticSearch 异常是什么意思:“所有分片失败”和“未找到 id 的搜索上下文”?
- python - 使用 Pandas 提取配置文件(看起来像 K/V 但不是)
- python - 如何比较两个列表中的项目并根据结果创建一个新列表?
- android - GestureDetector 不适用于 Android PdfViewer lib