Онлайн компилятор C

#include <stdio.h> int nod(int a, int b) { int c = 1, result; while (c > 0) { c = a % b; if (c == 0) { result = b; } else { a = b; b = c; } } return result; } int main() { int x, y; scanf("%d%d", &x, &y); printf("%d", nod(x, y)); return 0; }
这段代码试图用辗转相除法(欧几里得算法)计算两个整数的最大公约数。但存在逻辑错误,导致函数可能返回未初始化的值。

- 在 while 循环中,当 `c` 变为 0 时,你设置了 `result = b`,但循环条件 `c > 0` 此时为假,循环会立即结束,此时 `result` 确实被赋值了。然而,如果第一次取模 `c` 就不为 0,你会进入 else 分支更新 `a` 和 `b`,但此时 `result` 没有被赋值,循环继续。当后续某次 `c` 变为 0 时,虽然设置了 `result`,但循环结束前最后一次迭代可能没有正确更新 `result`。

- 更关键的问题是:当 `c` 为 0 时,你本应直接返回 `b`,但你的代码却先设置 `result` 然后继续循环,而循环条件 `c > 0` 此时为假,循环退出,返回 `result`。这看起来似乎可行,但考虑一种情况:如果初始输入中 `a` 能被 `b` 整除,第一次取模 `c` 就是 0,此时 `result = b`,循环结束,返回正确。但如果需要多次迭代,最后一次迭代中 `c` 变为 0 时,你设置 `result = b`,但循环条件检查时 `c` 已经是 0,循环退出,返回 `result`,这也能工作。然而,你的代码在 else 分支中更新了 `a` 和 `b`,但没有更新 `result`,导致在循环的某些路径中 `result` 可能未被赋值就返回。

- 提示:思考 while 循环的条件和循环体内何时应该直接返回结果,而不是依赖循环结束后才返回。考虑在检测到 `c == 0` 时立即返回 `b`,而不是先赋值给 `result` 再等待循环结束。