2

Cを学んでいます。

物事を試し、その言語で確立されたプログラマーからフィードバックを受け取ると、プログラミングをよく学ぶことができます。

strcmp()できると思ったからといって、独自の関数を作成することにしました:)

int strcompare(char *a, char *b) {
    while (*a == *b && *a != '\0') {
        a++;
        b++;
    }
    return *a - *b;
}

の状態でポインタをインクリメントすることで動作させようとしましたが、 のwhile実行方法がわかりませんでしたreturn。私は、1行でできる限り多くのことを行うCスタイルのコードを目指していました:)

確立された C プログラマーからフィードバックをいただけますか? このコードを改善できますか? 悪い習慣はありますか?

ありがとう。

4

6 に答える 6

3

while ステートメントですべてを実行したい場合は、次のように記述できます。

while (*a != '\0' && *a++ == *b++) {}

個人的には、このスタイルのプログラミングの大ファンというわけではありません。とにかく、読者は操作の順序を理解しようとするとき (そしてコードにバグがあるかどうかを判断するとき) に頭の中で「展開」する必要があります。メモリのバグは C では特に潜行性が高く、1 バイト先またはそれより前にメモリを上書きすると、元の原因から離れて、あらゆる種類の不可解なクラッシュやバグがずっと後で発生する可能性があります。

C プログラミングの最新のスタイルでは、簡潔さよりも正確性、一貫性、規律が重視されます。プレインクリメント操作とポストインクリメント操作のような簡潔な式の機能は、もともとコンパイラーがより優れたマシン コードを生成できるようにするための方法でしたが、最近ではオプティマイザー自身が簡単にそれを行うことができます。

@sbi が書いているconst char *ように、単純なchar *引数よりも引数の方が好きです。

于 2010-10-24T12:29:54.833 に答える
2
  1. a関数はとの内容を変更しませんb。文字列へのポインターを取得することで、おそらくそれを発表する必要がありconstます。
  2. ほとんどの C スタイルは、他の多くの言語のスタイルよりもはるかに簡潔ですが、巧妙になりすぎないようにしてください。(あなたのコードでは、いくつかの条件がループ条件でANDされているため、そこにインクリメントを入れる方法はないと思うので、これはスタイルの問題ではなく、正確さの問題です。)
于 2010-10-24T12:24:43.360 に答える
1

可能な限り置くことがCスタイルと見なされるため、わかりません...むしろ(難読化された)Perlをそれに関連付けます..

これをしないでください。最善の方法は、1 行に 1 つのコマンドです。コードをデバッグしようとすると、その理由がわかります:)

あなたの実装に:私にはかなり問題ないようですが、a が常に b よりも大きいことを知ることができないため、*b も '\0' ではないという条件を付けます...そうしないと、未割り当てで読み取るリスクがありますメモリー...

于 2010-10-24T12:23:15.027 に答える
1

から、これは面白いと思うかもしれませんeglibc-2.11.1。独自の実装と大差ありません。

/* Compare S1 and S2, returning less than, equal to or
   greater than zero if S1 is lexicographically less than,
   equal to or greater than S2.  */
int
strcmp (p1, p2)
     const char *p1;
     const char *p2;
{
  register const unsigned char *s1 = (const unsigned char *) p1;
  register const unsigned char *s2 = (const unsigned char *) p2;
  unsigned reg_char c1, c2;

  do
    {
      c1 = (unsigned char) *s1++;
      c2 = (unsigned char) *s2++;
      if (c1 == '\0')
    return c1 - c2;
    }
  while (c1 == c2);

  return c1 - c2;
}
于 2010-10-24T12:26:13.433 に答える
0

(insigned) char の制限が int の制限以上である場合、整数オーバーフローのため、この関数は失敗します。

たとえば、制限が 0...65536 の 16 ビット char と制限が -32768...32767 の 16 ビット int を持つ DSP でコンパイルする場合、"/uA640" と "A" のような文字列を比較しようとすると、結果は負になりますが、これは正しくありません。

これはエキゾチックで奇妙な問題ですが、ユニバーサル実装を作成すると表示されます。

于 2010-10-24T22:48:49.483 に答える
0

非常に微妙なバグ:strcmpとして解釈されたバイトを比較しますunsigned charが、関数はそれらをchar(ほとんどの実装で署名されている) として解釈しています。これにより、ASCII 以外の文字が ASCII の後ではなく前にソートされます。

于 2010-10-24T21:02:34.960 に答える