C语言数组元素LCM求解程序陷入死循环,请求排查问题
死循环原因分析与修复方案
核心问题:整数溢出
你的程序死循环的根本原因是int类型的溢出。1到20的最小公倍数是2329089562800,而32位int的最大值仅为2147483647,远小于这个值。当数组元素翻倍到超过int范围时,会触发有符号整数溢出(C语言中属于未定义行为),元素会变成负数或异常值,导致are_same()永远无法返回1,程序陷入死循环。
函数逻辑验证
are_same()函数逻辑正确:遍历数组对比所有元素与第一个元素是否相等,判断准确。get_min_index()函数逻辑正确:能正确找到数组中最小值的索引,即使存在多个相同最小值,后续循环也会依次处理到这些元素。
修复方案
1. 更换数据类型为long long
将数组、函数参数及相关变量的类型从int改为long long,避免溢出。64位long long的最大取值可达9223372036854775807,完全能容纳1-20的最小公倍数。
2. 调整函数与输出格式
- 修改
are_same和get_min_index的参数类型为long long数组。 - printf输出时使用
%lld格式符对应long long类型。
修正后的代码
#include <stdio.h> int are_same(long long array[], int length) { for (int i = 1; i < length; i++) { if (array[0] != array[i]) { return 0; } } return 1; } int get_min_index(long long array[], int length) { long long min_value = array[0]; int min_index = 0; for (int i = 1; i < length; i++) { if (array[i] < min_value) { min_value = array[i]; min_index = i; } } return min_index; } int main(void) { long long divisors[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; int length = sizeof(divisors) / sizeof(divisors[0]); int min_index; do { min_index = get_min_index(divisors, length); divisors[min_index] += divisors[min_index]; } while (!are_same(divisors, length)); printf("lcm=%lld\n", divisors[0]); return 0; }
运行结果
修复后的程序会正确输出:lcm=2329089562800,不会再陷入死循环。
内容的提问来源于stack exchange,提问作者jvkloc
相关产品推荐
相关产品推荐

