質問

" strings"を比較する正しい方法を知っています。 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
}

最初の printf は、 1 を正しく印刷し、それらが等しくないことを通知します。しかし、文字配列を比較すると、 == 0 を返している理由を誰かに説明できますか?

最初の printf 1 (つまり、等しい)を返し、文字配列が 0

役に立ちましたか?

解決

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

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

char []行は、データを変数にコピーすることで変数を作成するため、実行中にスタックの異なるアドレスに保存されます。

他のヒント

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

文字列ではなくアドレスを比較しています。最初の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

Wait a sec ... 1は真を意味し、0は偽を意味します。だからあなたの説明は部分的に逆です。最初の2つの文字列が等しいように見える理由については、コンパイラは定数文字列(s1 / 2)を一度だけ作成しました。

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

s3 == s4 でも同じです。それは" 配列がポインターになります"職場で。

そして、比較結果の意味が間違っています:

0 == 0; /* true; 1 */
42 == 0; /* false; 0 */
"foo" == "bar"; /* false (the addresses are different); 0 */

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は同じ静的メモリブロックを指していますが、その動作が移植可能であるとは思わないでしょう。

文字列を比較することはできませんが、ポインターを比較することはできます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top