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

时间:2012-05-27 09:21:32

标签: c

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

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

返回 only_ascending_letters(字符串,索引+ 1);”

 #include <stdio.h>

    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]<='z')||(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 <stdio.h>

    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]<='z')||(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;

    }

3 个答案:

答案 0 :(得分:7)

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

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

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

答案 1 :(得分:1)

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

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

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

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

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

  

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

答案 2 :(得分:0)

您有两个退出条件。你要么运行字符串的结尾,在这种情况下你的条件符合升序字符,你返回字符串的长度,或者你找到一个未通过升序测试的字符,在这种情况下你返回-1。

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