我有这个C代码,我确信它不起作用,但确实如此。
#include <stdio.h>
int* find (int* a, int val) {
if (*a == val)
return a;
else
find(a+1, val);
}
int main() {
int a[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int *b;
b = find(a, 7);
printf("%d\n", *b);
return 0;
}
当然,我从gcc收到警告,因为它在find
函数的else分支中缺少return语句。但是,它完美无缺。
为什么会这样?如何通过递归函数返回int?当然,最后一次调用返回一个int,但我在void上下文中调用它。
答案 0 :(得分:7)
此代码不是有效的C代码,并且未定义此类代码的行为。
它工作的一个原因可能是在find
中的最后一次调用之后没有操作,其中可能导致递归调用的返回值保留在返回寄存器中(可能EAX)。
但同样 - 行为未定义。
答案 1 :(得分:3)
此似乎正在运行,但它是未定义的行为。只是在您的特定实现/平台b
中获取从find
返回的最新值。但是,在不同的实现/平台上,这也可能会崩溃。
答案 2 :(得分:2)
假设您打算写find
而不是trova
(我知道有一天学习意大利语会派上用场:),答案是这不能很好地完成。由于未定义的行为,它纯粹是偶然“有效”。
最有可能的是,最深的递归调用将返回值推送到某个寄存器,高级调用不会触及,因为它们没有返回语句,并且当调用者检查该寄存器时,返回值为最深的呼吁仍在那里。不过,你不能依赖它。
答案 3 :(得分:-1)
我找不到引用,但我记得多年前,在GCC中,返回值寄存器(在CPU上分配)总是有最后一个返回值,所以如果你计算了一些值并返回没有值,之前的值仍然存在。使用这个“功能”似乎是一种不好的做法。
也许也可以看到
C: default return value if no value is given?
那说: Uniballer 2012年6月15日,01:44 C语言没有定义该行为,因为您没有在函数声明中执行的操作中执行该操作。实际上,在x86上,函数的值将是返回时寄存器eax中的任何内容。