0

一種の演習として、文字列比較をできるだけ短く実装したいと思います。コードは以下のとおりです。

#include <stdio.h>

int strcmp(const char* a, const char* b)
{
     for(;a && b && *a && *b && *a++==*b++;);return *a==*b;
}


int main ()
{
    const char* s1 = "this is line";
    const char* s2 = "this is line2";
    const char* s3 = "this is";
    const char* s4 = "this is line";


    printf("Test 1: %d\n", strcmp(s1, s2));
    printf("Test 2: %d\n", strcmp(s1, s3));
    printf("Test 3: %d\n", strcmp(s1, s4));
    printf("Test 4: %d\n", strcmp(s1, s1));
    printf("Test 5: %d\n", strcmp(s2, s2));

    return 0;
}

結果は次のとおりです。

Test 1: 0
Test 2: 0
Test 3: 1
Test 4: 0
Test 5: 0

文字列をそれ自体と比較する場合、何が問題になっていますか?

注: より短い解決策があることは知っていますが、自分で見つけたいと考えています。

編集: コンパイラはgccUbuntu の下にあります。

4

4 に答える 4

3

同じ機能を提供しない場合は、標準ライブラリの関数と同じように関数を呼び出さないでください。そうするとき、あなたは微妙な方法で多くのものを壊します。どうやらそれがここのバグでした。

ここにさらにいくつかの有用なコメントを追加します。代わりに while ループを使用してください。引数が NULL であることをチェックしないでください。これは悪いスタイルです。そのために for ループが終了したとしても、return ステートメントは NULL を逆参照するため、とにかくクラッシュします。

于 2013-07-18T10:54:50.610 に答える
2

コードを GCC-4.4.7 でテストしたところ、同じ結果が得られました。GCC ページでは、http: //gcc.gnu.org/projects/optimize.htmlの最適化について説明していますstrcmp

GCC は、1 つの文字列が定数である strcmp (および memcmp) を最適化して、連続するバイトをインラインの既知の定数と比較することができます。

関数の名前を変更すると、次のように期待される結果が得られます。

$ cc yourcode.c
$ ./a.out 
Test 1: 0
Test 2: 0
Test 3: 1
Test 4: 0
Test 5: 0
$ cc -D strcmp=strcmp1 yourcode.c
$ ./a.out 
Test 1: 0
Test 2: 0
Test 3: 1
Test 4: 1
Test 5: 1
于 2013-07-18T11:07:21.410 に答える
1

等しくない 2 つの文字が見つかった場合は、ポインターをインクリメントしますaが、文字列が異なる場所の後ろの文字を比較した結果を返しbます。そのようにする方が良い:*a==*b

for(;*a && *b && *a==*b; a++, b++) ;
return *a==*b;

そして、関数の名前を変更してください。それはstrcmp以外のすべてです。

テストケース4を説明していない編集strcmp()ですが、他の回答が示すように関数名を使用することで説明されています。

于 2013-07-18T10:56:31.477 に答える