3

再帰関数を試すのはこれが初めてです。私が作成したこの関数は、昇順の文字のみが含まれている場合は文字列のサイズを返し、含まれていない場合は-1を返します。

2番目の「リターン」を取り出した後、なぜ両方のコードで機能するのかわかりません。一方はもう一方よりも無駄ですか?いくつかの洞察をいただければ幸いです。

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

    }
4

3 に答える 3

7

はい、絶対に返品が必要です。C言語のルールはこの問題について少し緩いことに注意してください。戻り値を使用していなかった場合は、戻り値がなくても問題ありません。ただし、戻り値を使用するため、returnステートメントが必要です。

表示されるのは、一部のアーキテクチャで機能する実装の詳細が、既知のレジスタをその値(i386ではeax)に設定することによって(整数値)を返すことが原因である可能性があります。したがって、最下部の再帰呼び出しがreturnこのレジスタを実行して設定し、その間の呼び出しがそのレジスタを踏みつけない場合は、それが一種の機能を果たしていることがわかります。ただし、それに依存してはなりません。

優れたコンパイラは、これが末尾再帰呼び出しであることを認識し、基本的に同じ方法で両方のバリアントをコンパイルすることに注意してください。

于 2012-05-27T09:25:57.900 に答える
1

まずmain()、int(実際にはintと互換性のある型)を返します。

次に、コードをさらにフォーマットする必要があります。空白はあなたの友達であり、改行も同様です。ほとんどが画面外で実行されたため、返されないコードが実際に正しいかどうかを判断するのは困難でした。

第三に、常にすべての[合理的な]警告を有効にして作業する必要があります。そうすることで、欠落している返品条件とvoid main()

答えとしては、@jpalecekはそれを提供する素晴らしい仕事をしました。未定義の振る舞いは獣であるということだけを付け加えたいと思います。あなたがそれに頼っているなら、あなたがそれを再びコンパイルすることを決めた、それを実行している間に音楽を演奏した、または月の満ち欠けが変わったという理由だけで、「動作中の」プログラムはそうしなくなるかもしれません。

[99]標準で見つけたのは§6.9.1節12だけでした:

関数を終了する}に到達し、関数呼び出しの値が呼び出し元によって使用される場合、動作は定義されていません。

于 2012-05-27T09:51:32.917 に答える
0

2つの終了条件があります。文字列の終わりを使い果たした場合は、昇順の文字の条件が満たされ、文字列の長さを返します。または、昇順のテストに失敗した文字を見つけた場合は、-1を返します。

再帰関数の呼び出しから値を返さないことは、コンパイラーの一部の実装では機能する可能性がありますが、異なるコンパイラーまたは異なる最適化フラグを使用すると、機能しない可能性があるため、コードで戻り値を保持する必要があります。

于 2012-05-27T09:45:58.143 に答える