2012-05-27 27 views
3

這是我第一次玩遞歸函數,我寫的這個函數返回一個字符串的大小,如果它只包含字母升序,如果不是,則返回-1。C:中的遞歸函數總是有必要的嗎?

我不明白爲什麼它適用於這兩個代碼,我拿出第二個「返回」後。比另一個更浪費嗎?希望有些見解。

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; 

    } 

「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; 

    } 
+2

主要應該返回int。 – wildplasser

+0

看看使用apache commons的StringUtils類來簡化測試,如果字符是字母的。 –

回答

7

是的,你絕對需要回報。請注意,C語言規則在這個問題上有點鬆懈,如果你沒有使用返回值,沒有它就沒問題。但是,您使用返回值,因此您需要返回語句。

您看到的可能是由某些體系結構上的函數通過將已知的寄存器設置爲該值(i386上的eax)返回(整數值)的實現細節引起的。因此,如果最下面的遞歸調用return並設置了該寄存器,並且中間調用不會在該寄存器上跺腳,那麼您會發現它有些作用。但是,你不能依賴那個。

請注意,好的編譯器會認識到這是一個尾遞歸調用,並且基本上以相同的方式編譯這兩個變體。

+0

但是爲什麼?它的工作原理沒有它 – nofe

+0

@nofe:看編輯 – jpalecek

+0

+1爲整潔的細節 – Jay

0

您有兩個退出條件。您要麼跑掉字符串的末尾,在這種情況下,符合升序字符的條件會得到滿足,並返回字符串的長度,否則您會發現一個字符不符合升序測試的要求,在這種情況下,您將返回-1。

沒有將調用中的值返回給遞歸函數可能適用於編譯器的某些實現,但使用不同的編譯器或不同的優化標誌,它可能無法正常工作,因此您應該在代碼中保留返回值。

1

首先,main()返回一個int(實際上是一個與int兼容的類型)。

其次,你應該更多地格式化你的代碼。空白是你的朋友,也是換行符。很難判斷沒有返回的代碼是否確實是正確的,因爲大部分代碼都是在屏幕外運行的。

第三,您應該始終使用所有啓用的[合理]警告。這樣做可能會發現缺失的退貨情況,以及void main()

至於答案,@jpalecek提供了很好的工作。我只想補充說,未定義的行爲是一個野獸。如果你依賴它,一個「工作」程序可能會停止這樣做,因爲你決定再次編譯它,在運行時播放一些音樂,或者改變月亮的相位。

所有我能找到的[99]標準爲§6.9.1第12

如果}終止達到的功能,並且使用 函數調用的價值通過調用者,行爲是不確定的。

+0

額外挑剔的評論:'main()'是個例外。如果'main'的返回類型與'int'兼容,則到達終止main的'}'將返回值'0'。 (C99和n1570中的5.1.2.2.3)。我害怕看到有那麼一天會被利用。 –

+0

@DanielFischer:我以爲只有C++。謝謝。在C99中添加了 – aib

+0

。我不認爲這是C99中更好的變化之一。 –