2

次のコードは、32 ビットと 64 ビットのオペレーティング システムで動作が異なります。

char *cat = "v,a";
if (strcmp(cat, ",") == 1)
    ...

上記の条件は 32 ビットでは true ですが、64 ビットでは false です。なぜこれが違うのだろうか?32 ビット OS と 64 ビット OS はどちらも Linux (Fedora) です。

4

3 に答える 3

12

このstrcmp()関数は、引数 1 が引数 2 よりも前にある場合は負の値を返し、それらが同じ場合はゼロを返し、引数 1 が引数 2 の後にある場合は正の値を返すように定義されています。

+1返される値がいつでもまたはになるという保証はありません-1。その仮定に基づく等価テストはすべて誤りです。の 32 ビット バージョンと 64 ビット バージョンが特定の文字列比較に対して異なる数値を返すことは考えられますが、 fromstrcmp()を探すテストには本質的に欠陥があります。+1strcmp()

比較コードは次のいずれかである必要があります。

if (strcmp(cat, ",") >  0)    // cat >  ","
if (strcmp(cat, ",") == 0)    // cat == ","
if (strcmp(cat, ",") >= 0)    // cat >= ","
if (strcmp(cat, ",") <= 0)    // cat <= ","
if (strcmp(cat, ",") <  0)    // cat <  ","
if (strcmp(cat, ",") != 0)    // cat != ","

共通のテーマに注意してください — すべてのテストは 0 と比較されます。

if (strcmp(cat, ","))   // != 0
if (!strcmp(cat, ","))  // == 0

個人的には、ゼロとの明示的な比較を好みます。私は頭の中で省略形を適切な省略形に変換します (そして、そうさせられることに憤慨します)。


strcmp()の仕様には次のように記載されていることに注意してください。

ISO/IEC 9899 : 2011 §7.24.4.2関数strcmp

¶3関数は、 が指す文字列が が指す文字列よりもstrcmp大きい、等しい、または小さいため、ゼロより大きい、等しい、または小さい整数を返します。s1s2

+1orについては何も述べていません-1。結果の大きさに依存することはできず、その符号性 (または文字列が等しい場合はゼロ) のみに依存します。

于 2013-08-07T05:53:24.817 に答える
5

標準関数は、関連するヘッダー ファイルをインクルードしないなどのばかげたことをしない限り、OS の「噛み付き」に基づいて異なる動作を示すことはありません。ルールに違反しない限り、標準で指定された動作を正確に示す必要があります。それ以外の場合、コンパイラは閉じていますが、C コンパイラではありません。

ただし、標準によると、からの戻り値strcmp()はゼロ、正または負のいずれかであり、ゼロ以外の場合に +/-1 であるとは限りません。

あなたの表現は次のように書く方が良いでしょう:

strcmp (cat, ",") > 0

使い方のstrcmp (cat, ",") == 1誤りは、OS が 32 ビットか 64 ビットかは関係ありません。すべては、戻り値を誤解していることに関係しています。ISO C11標準から(私の太字):

strcmp 関数は、 s1 が指す文字列が s2 が指す文字列より大きい、等しい、または小さいため、ゼロより大きい、等しい、または小さい整数を返します。

于 2013-08-07T05:51:54.977 に答える