3

this is my first time playing with recursive functions, and this function that I wrote returns the size of a string if it contains only letters in ascending order, and if not it returns -1.

I don't understand why it works for both codes, after I took out the second "return". Is one more wasteful than the other? Would appreciate some insight.

with "return 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])) 
            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;

    }
4

3 回答 3

7

是的,您绝对需要退货。请注意,C 语言规则对这个问题有点松懈,如果你没有使用返回值,没有它也可以。但是,您使用返回值,因此您需要 return 语句。

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

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

于 2012-05-27T09:25:57.900 回答
1

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

其次,您应该更多地格式化您的代码。空格是你的朋友,换行符也是。很难判断没有返回的代码是否真的正确,因为大部分代码都跑出了屏幕。

第三,您应该始终启用所有 [reasonable] 警告。这样做会捕获丢失的返回条件,以及void main().

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

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

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

于 2012-05-27T09:51:32.917 回答
0

你有两个退出条件。您要么跑出字符串的末尾,在这种情况下,满足升序字符的条件并返回字符串的长度,要么找到未通过升序测试的字符,在这种情况下,您返回 -1。

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

于 2012-05-27T09:45:58.143 回答