0

おそらく奇妙な質問です。

私は現在、次のことが真に等しい理由を理解するのに苦労しています。つまり、「HelloWorld」がコンソールに出力されますか?Cでの文字列比較は、 strcmpなどを使用して行う必要があると常に考えていました。

char *a = "Hello";
char *b = "Hello";

if(a == b)
{
    printf("Hello World\n");
}

また、これはアドレスが同等である場合にのみ真になると思いましたか?それらが文字通りであるという事実ですか?

PS。はい、これは割り当てとはほとんど関係ありませんが、私は頭のてっぺんから上記を思いついたところです。-これは割り当てにまったく答えません。

4

5 に答える 5

5

この言語では、文字列リテラルをどこにどのように格納するかについての要件はありません。あなたが知っているのは、それらには静的な保存期間があり、データを変更しようとしてはならないということだけです。標準には、2つの異なる文字列リテラルが異なるアドレスを持つことを要求するものはなく、実装が文字列リテラルデータを重複排除することは完全にもっともらしいです。

一方、2つの同一の文字列リテラルを同じアドレスに格納する必要はないため、アドレスを比較してもほとんど意味がありません。常に文字列の内容strcmpを比較するために使用します。

于 2012-09-26T00:58:08.620 に答える
3

コードに直接入力した同一のリテラルは、最適化の目的で実際には同じメモリ位置を指します。

この場合のコンパイラは、「Hello」を固定メモリに1回配置してから、そのメモリをポイントabます。

何が起こっているのかをより詳細に理解するには、このプログラムをコンパイルして(最初に文字列リテラルの束を追加して)、gdbまたはvalgrindまたはその他のメモリインスペクターを使用して、文字列リテラルを指すメモリを手動で確認することをお勧めします-あなた標準的なケースでは、gccはすべての文字列リテラルをメモリにまとめ、同一の文字列リテラルを再利用します。

于 2012-09-26T00:53:54.470 に答える
2

aとbは文字へのポインタです。

ポインタは基本的にメモリアドレスを格納します。a変数とb変数は「hello」という単語を保存しませんが、「hello」という単語が保存されているメモリアドレスを保存します。

プログラムでaとbを印刷して、それらの値を確認します。それは次のようになります:632176またはそのようなもの、そしてそれらは等しくなります。

したがって、コードa == bは基本的に「aとbは同じメモリアドレスを指しているのですか?」と言っています。「hello」は定数文字列であり、メモリに書き込まれるのは1回だけなので、そうなります。

于 2012-09-26T00:58:14.253 に答える
1

ここで起こっていることは、とという2つのポインタがあるということ*aです*b。次に、ご存知のように、ポインタは特定のメモリ位置を指します。ここで、との両方*a*bまったく同じ文に等しく設定されている場合、それはそれに続きabメモリアドレスを指しています。ただし、コンパイラはポインタが同じ文であることに気付くため、最適化の目的で、ポインタがまったく同じメモリアドレスを指すように設定します。

このため、何が起こるかは次のようになります。

a = 0xFFFFFFFF;
b = 0xFFFFFFFF;
if(0xFFFFFFFF == 0xFFFFFFFF){
    // Code
}

これらを比較すると、コンパイラはそれを次(0xFFFFFFFF == 0xFFFFFFFF)のように認識します。コンパイラはそれらが等しいことを認識し、結果としてif statementtrueになり、次のように表示されます。Hello, World

ただし、これは異なるコンパイラでは発生しない可能性があるため、コンパイラ間で異なる結果が得られる可能性があります。ただし、この動作はgccで機能します。したがって、その場合は、strcmpこのようなランダムな動作を避けるために、常に比較に使用する必要があります。

于 2012-09-26T01:00:26.640 に答える
1

同じ値を指す2つのポインターがある場合、コンパイラーは両方のポインターを同じメモリーにポイントするだけだと思います。そのより効率的です。しかし、Cでは、このような場合でも常にstrcmpを使用します。

于 2012-09-26T01:00:36.590 に答える