为何空for循环会影响C程序的运行结果?
问题描述
最初编写的代码运行正常:
#include <stdio.h> int main(){ int a,b,i; scanf("%c",&a); if (a<=122 && a>=97) a=a-32; b=a-64; printf("%d",b); return 0; }
但添加一个空for循环后,代码运行结果出现异常:
#include <stdio.h> int main(){ int a,b,i; scanf("%c",&a); if (a<=122 && a>=97) a=a-32; b=a-64; printf("%d",b); for(i=1;i <= 5;i++){ ; } return 0; }
测试输入'A'时,第一个程序输出1,第二个程序却输出32557这类奇怪数值。已知将变量a的类型改为char后程序恢复正常,想了解问题的成因。
问题成因分析
这本质是类型不匹配导致的未初始化内存访问问题,具体细节如下:
scanf("%c", &a)中的%c格式符要求传入char*类型指针,用来存储1字节的字符数据,但你定义的a是int类型(多数系统中占4字节),传入的&a是int*指针。- 执行
scanf时,只会向a对应的内存地址写入1字节的字符ASCII值(比如输入'A'时写入0x41),但int类型剩下的3字节内存属于未初始化状态,里面是随机的垃圾值。 - 第一个程序中,编译器的栈布局或优化巧合地让
a的高3字节内存值为0,所以a的整体值刚好是正确的ASCII码65,计算b=a-64自然得到1。 - 添加空for循环后,栈上变量的布局发生变化,
a的高3字节不再是0,而是保留了随机垃圾值,导致a的实际值变成一个包含垃圾数据的大整数,此时计算b=a-64就会得到像32557这类奇怪的数值。 - 当把
a改为char类型时,scanf刚好能填满整个变量的内存空间,没有剩余的未初始化字节,所以a的值始终是正确的字符ASCII码,程序恢复正常。
内容的提问来源于stack exchange,提问作者Tauschii
相关产品推荐
相关产品推荐

