这段代码试图计算两个整数 n 和 m 的最大公约数(GCD),但存在一个逻辑错误。 代码先通过交换确保 a 是较小的数,b 是较大的数,然后使用辗转相除法(欧几里得算法)循环计算。循环中,每次将 a 的值暂存到 c,然后更新 a 为 b 除以 a 的余数,再将 b 设为原来的 a(即 c)。循环结束时,b 应该是最大公约数。 - 问题在于:辗转相除法中,每次迭代后,新的除数应该是上一次的余数,而被除数应该是上一次的除数。你的代码在循环中把 b 更新为 c(即旧的 a),但此时 a 已经被更新为余数。这导致下一次循环时,a 是余数,b 是旧的除数,这符合算法。然而,循环条件 a != 0 是正确的,但最终输出 b 时,b 存储的是最后一次循环中旧的除数,也就是余数为 0 之前的那个除数,这确实是最大公约数。所以逻辑上似乎正确,但有一个细节:当 a 初始为 0 时(比如 n 和 m 相等且为 0?),循环不会执行,此时 b 是较大的数,但 0 和 0 的最大公约数未定义,而 0 和正数的最大公约数是那个正数。你的代码在 n=m=0 时会输出 b=0,这可以接受。但更关键的是,如果 n 或 m 为 0,你的交换逻辑可能导致 a 为 0,循环不执行,输出 b 为另一个数,这正确。所以代码基本正确,但有一个潜在问题:当 n 和 m 都是 0 时,输出 0,而数学上 0 和 0 的最大公约数通常未定义,但这不是大问题。 - 不过,你的代码中变量 c 的使用可以简化。实际上,辗转相除法的标准写法不需要额外变量 c,可以直接用临时变量。但这不是错误。 - 提示:检查当 n 或 m 为负数时的情况。你的代码没有处理负数,但 scanf 读取的是 int,负数输入会导致算法出错,因为取模运算在 C 中对于负数结果可能为负。考虑是否需要处理负数,或者假设输入为正整数。 - 另一个