C语言for循环变量出现超大异常值的原因及解决方法
数组遍历中循环变量值异常及最小值查找失败的原因与修复
问题重现
需求是读取4个double类型值存入数组,遍历数组找出最小值及其索引,但运行时循环变量c出现随机异常值,输出结果完全不符合预期。
读取数组的代码:
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> int main(int argc, char *argv[]) { double input[4]; int i; for (i = 0; i < 4; i++) { scanf("%d", &input[i]); }
核心逻辑代码:
double smallest = input[0]; int smallestIdx = 0; int c = 0; for (c = 0; c < 4; c++) { printf("input[c] = %d; c = %i; smallest = %d; smallestIdx = %i\n", input[c], c, smallest, smallestIdx); if (input[c] < smallest) { smallest = input[c]; smallestIdx = c; } } return 0; }
运行输出(异常):
input[c] = 1; c = 6422476; smallest = 0; smallestIdx = 1 input[c] = 2; c = 237326259; smallest = 1; smallestIdx = 1 input[c] = 3; c = 6422200; smallest = 2; smallestIdx = 1 input[c] = 4; c = 4200416; smallest = 3; smallestIdx = 3
问题原因
核心问题是格式符与变量类型不匹配,触发了C语言的未定义行为:
- 读取阶段:
input是double类型数组,但scanf使用了整数格式符%d。double占8字节,int占4字节,用%d读取会错误地写入4字节数据到8字节的double变量中,剩余4字节的内存被破坏,后续的循环变量c等变量的内存空间被篡改,导致出现随机值。 - 输出阶段:
printf用%d输出double类型的input[c]和smallest,格式符不匹配会导致输出错误的数值,同时进一步加剧内存访问的异常。
修复方案
将所有涉及double类型的输入输出格式符替换为%lf(scanf必须用%lf读取double,printf可以用%lf或%f,统一用%lf更规范):
修复后的完整代码:
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> int main(int argc, char *argv[]) { double input[4]; int i; // 用%lf读取double类型 for (i = 0; i < 4; i++) { scanf("%lf", &input[i]); } double smallest = input[0]; int smallestIdx = 0; int c = 0; for (c = 0; c < 4; c++) { // 用%lf输出double类型,%d输出int类型 printf("input[c] = %lf; c = %d; smallest = %lf; smallestIdx = %d\n", input[c], c, smallest, smallestIdx); if (input[c] < smallest) { smallest = input[c]; smallestIdx = c; } } // 最后输出结果 printf("最小值为:%lf,索引为:%d\n", smallest, smallestIdx); return 0; }
修复效果
修复后,循环变量c会正常从0到3依次取值,输入的double值能被正确读取和输出,最小值查找逻辑也能正常工作,输出结果符合预期。
内容的提问来源于stack exchange,提问作者T. Feix
相关产品推荐
相关产品推荐

