4

C で「文字列」を比較する正しい方法は を使用することstrcmpですが、いくつかの文字配列を==演算子と比較してみましたが、奇妙な結果が得られました。

次のコードを見てください。

int main()
{
    char *s1 = "Andreas";
    char *s2 = "Andreas";

    char s3[] = "Andreas";
    char s4[] = "Andreas";

    char *s5 = "Hello";

    printf("%d\n", s1 == s2); //1
    printf("%d\n", s3 == s4); //0
    printf("%d\n", s1 == s5); //0
}

最初のものは、それらが等しくないことを示すprintfa を正しく出力します。しかし、文字配列を比較するときにが返される1理由を誰かが説明できますか?==0

printf最初の配列が aを返している1(つまり、等しい) のに、文字配列が a を返している理由を誰かが説明してくれませんか0?

4

7 に答える 7

20

== はメモリアドレスを比較しています。
スペースを節約するために、コンパイラが s1 と s2 が同じ静的データを指すようにしている可能性があります。

すなわち。コードの最初の 2 行の「Andreas」は、実行可能データに格納されます。C 標準では、これらの文字列は定数であると規定されているため、2 つのポインターが同じストレージを指すように最適化されています。

char[] 行は、データを変数にコピーすることによって変数を作成するため、実行中にスタック上の別のアドレスに格納されます。

于 2009-11-26T00:09:20.647 に答える
4

ええと... 1 を出力すると、それら等しい==ことを意味します。文字列の相対的な順序を返す strcmp とは異なります。

于 2009-11-26T00:10:51.347 に答える
2

文字列ではなくアドレスを比較しています。最初の 2 つは一定で、一度だけ作成されます。

int main()
{
    char *s1 = "Andreas";
    char *s2 = "Andreas";

    char s3[] = "Andreas";
    char s4[] = "Andreas";

    char *s5 = "Hello";

    printf("%d\n", s1 == s2); //1
    printf("%p == %p\n", s1, s2);
    printf("%d\n", s3 == s4); //0
    printf("%p != %p\n", s3, s4);
    printf("%d\n", s1 == s5); //0
    printf("%p != %p\n", s1, s5);
}

私のコンピューターに出力しますが、アイデアはわかります:

1
0x1fd8 == 0x1fd8
0
0xbffff8fc != 0xbffff8f4
0
0x1fd8 != 0x1fe0
于 2009-11-26T00:15:09.880 に答える
1

s1 == s2(char*) == (char*)「 」またはアドレスが同じであることを意味します。

についても同じですs3 == s4。これが、「配列がポインタに崩壊する」ことです。

そして、あなたは間違った比較の結果の意味を持っています:

0 == 0; /* true; 1 */
42 == 0; /* false; 0 */
"foo" == "bar"; /* false (the addresses are different); 0 */
于 2009-11-26T00:16:39.113 に答える
1

s1からs5までのすべての値は、char自体ではなく、 char のポインターです。したがって、比較しているのは、文字列自体ではなく、各文字列のメモリアドレスです。

このようにアドレスを表示すると、比較演算子が実際に何に取り組んでいるかを確認できます。

#include <stdio.h>

int main() {
  char *s1 = "Andreas";
  char *s2 = "Andreas";

  char s3[] = "Andreas";
  char s4[] = "Andreas";

  char *s5 = "Hello";

  printf("%p\n", s1); // 0x80484d0
  printf("%p\n", s2); // 0x80484d0
  printf("%p\n", s3); // 0xbfef9280
  printf("%p\n", s4); // 0xbfef9278
  printf("%p\n", s5); // 0x80484d8
}

文字列がメモリ内のどこに割り当てられるかは、実装によって異なります。この場合、s1とs2は同じ静的メモリブロックを指していますが、その動作が移植可能であるとは期待していません。

于 2009-11-26T00:22:19.273 に答える
1

ちょっと待ってください... 1 は true を意味し、0 は false を意味します。したがって、あなたの説明は部分的に逆です。最初の 2 つの文字列が等しいように見える理由について: コンパイラはその定数文字列 (s1/2) を一度だけ作成しました。

于 2009-11-26T00:12:41.723 に答える
0

文字列は比較できませんが、ポインタは比較できます。

于 2009-11-26T00:13:37.643 に答える