为何无末尾返回值的递归GCD函数仍能正确运行?
为什么没有返回语句的递归GCD函数能正常工作?
你的代码确实存在严重问题——这是典型的C语言未定义行为,只是测试时碰巧“正常”了,绝非正确的写法。
问题根源
你的gcd函数是返回int类型的非void函数,但在递归分支的末尾(gcd(b, q);这一行)没有写return语句。按照C标准,这种情况下函数的返回值是未定义的,编译器不保证任何结果。
为什么测试时看起来正常?
这完全依赖于你当前使用的编译器和CPU调用约定:
- 大多数常见的调用约定(比如x86的cdecl)会把函数的返回值存在特定寄存器中(比如eax)。
- 当递归走到最深层,触发
return b;时,正确的GCD值已经被写入了这个寄存器。 - 上层的递归调用虽然没写
return,但函数结束时没有修改这个寄存器的值,所以main函数最终读取到的还是那个正确的值。
但这绝对不可靠
这种“正常”是脆弱的巧合,只要出现以下情况,程序立刻会出错:
- 开启编译器优化(比如
-O2或-O3):编译器可能会在函数末尾插入清理代码,覆盖寄存器里的正确值。 - 更换编译器或CPU架构:不同平台的调用约定可能用不同的寄存器存储返回值,结果会变成垃圾值。
- 给函数添加任何额外代码:比如在递归调用后加个变量赋值,就会破坏寄存器中的值。
修正后的正确代码
只需要把递归调用的那一行加上return即可:
#include <stdio.h> #include <stdlib.h> int gcd(int a, int b); int main() { int a, b; scanf("%d%d", &a, &b); printf("GCD = %d.\n", gcd(a, b)); } int gcd(int a, int b) { if (a < b) { int tmp = a; a = b; b = tmp; } int q = a % b; if (q == 0) return b; return gcd(b, q); // 这里必须添加return }
内容的提问来源于stack exchange,提问作者Volkov Sergey
相关产品推荐
相关产品推荐

