C中的递归函数:返回总是必要的吗?

这是我第一次使用递归函数,我写的这个函数返回一个字符串的大小,如果它只包含升序的字母,如果不包含它返回-1。

在我拿出第二个“返回”之后,我不明白为什么它适用于这两个代码。 比另一个更浪费一个人吗? 会欣赏一些见解。

with“ return only_ascending_letters(string,index + 1);”

#include  int only_ascending_letters(char string[], int index); void main() { char string1[]="Hi my name is pete"; char string2[]="aabcdefg"; printf("the first string is %d and the second one is %d\n",only_ascending_letters(string1,0),only_ascending_letters(string2,0)); } int only_ascending_letters(char string[], int index){ if(!string[index]) return index; if(((string[index]>='a'&&string[index]='A'&&string[index]<='Z'))&&((string[index]<=string[index+1])||!string[index+1])) return only_ascending_letters(string, index+1); else return -1; } 

with“only_ascending_letters(string,index + 1);”

  #include  int only_ascending_letters(char string[], int index); void main() { char string1[]="Hi my name is pete"; char string2[]="aabcdefg"; printf("the first string is %d and the second one is %d\n",only_ascending_letters(string1,0),only_ascending_letters(string2,0)); } int only_ascending_letters(char string[], int index){ if(!string[index]) return index; if(((string[index]>='a'&&string[index]='A'&&string[index]<='Z'))&&((string[index]<=string[index+1])||!string[index+1])) /*Took out the return*/ only_ascending_letters(string, index+1); else return -1; } 

是的,你绝对需要回报。 请注意,C语言规则对此问题有点松懈,如果您没有使用返回值,没有它就没关系。 但是,您使用返回值,因此您需要return语句。

您所看到的可能是由某些体系结构上的函数返回(整数值)的实现细节引起的,方法是将一个众所周知的寄存器设置为该值(i386上的eax)。 因此,如果最底层的递归调用确实return并设置了该寄存器,并且中间的调用不会踩踏该寄存器,那么您会看到它有效。 但是,你不能依赖它。

请注意,好的编译器会认识到这是一个尾递归调用,并且基本上以相同的方式编译两个变量。

首先, main()返回一个int(实际上是一个与int兼容的类型)。

其次,您应该更多地格式化代码。 空格是你的朋友,和换行符一样。 很难判断没有返回的代码是否真的是正确的,因为大多数代码都是在屏幕外运行的。

第三,你应该始终使用所有[合理]警告启用。 这样做会捕获缺少的返回条件,以及void main()

至于答案,@ jpalecek提供了很好的工作。 我只想补充一点,未定义的行为是一头野兽。 如果你依赖它,一个“工作”程序可能会因为你决定再次编译它,在运行它时播放一些音乐,或月亮的阶段改变而停止这样做。

我在[99]标准中找到的全部是§6.9.1第12条

如果到达终止函数的},并且调用者使用函数调用的值,则行为未定义。

你有两个退出条件。 你要么跑掉字符串的末尾,在这种情况下你会遇到提升字符的条件并且你返回字符串的长度,或者你找到一个未通过升序测试的字符,在这种情况下你返回-1。

不返回从调用到递归函数的值可能对编译器的某些实现起作用,但是使用不同的编译器或不同的优化标志,它可能不起作用,因此您应该在代码中保留返回值。