5

そこで、次のテストを行いました。

char* a = "test";
char* b = "test";
char* c = "test\0";

そして今、質問:

1) それは保証されていa==bますか? 私はアドレスを比較していることを知っています。これは文字列を比較することを意図したものではなく、同一の文字列リテラルが単一のメモリ位置に格納されているかどうかを示しています

2)なぜそうしないa==cのですか?コンパイラは、それらが同じ文字列を参照していることを確認できるはずではありませんか?

3)すでに含まれている場合でも\0、末尾に余分なものが追加されていますか?c

3 つの異なる質問はしたくありませんでした。これらは何らかの関連があるように思われるからです。申し訳ありません。

注: タグは正しいです。私は C++ に興味があります。(ただし、C で動作が異なる場合は指定してください)

4

7 に答える 7

18

a == bであることが保証されていますか?

いいえ。ただし、§2.14.5/12で許可されています。

すべての文字列リテラルが異なるかどうか(つまり、重複しないオブジェクトに格納されるかどうか)は、実装によって定義されます。文字列リテラルを変更しようとした場合の影響は定義されていません。

そして、その最後の文からわかるようchar*に、代わりにを使用するchar const*と、問題のレシピになります(コンパイラはそれを拒否する必要があります。警告が有効になっていて、高い適合性レベルが選択されていることを確認してください)。

なぜa==cではないのですか?コンパイラは、それらが同じ文字列を参照していることを認識できるべきではありませんか?

いいえ、同じ文字配列を参照している必要はありません。1つには5つの要素があり、他の6つには要素があります。実装では、2つを重複するストレージに格納できますが、必須ではありません。

すでに\0が含まれている場合でも、cの最後に余分な\ 0が追加されていますか?

はい。

于 2012-05-24T17:24:41.090 に答える
6

1-絶対にありません。ただし、コンパイラが同じ静的文字列を共有することを選択した場合は、aは==bになる可能性があります。

2-同じ文字列を参照していないため

3-はい。

ここでの動作は、C++コンパイラがnon-constchar *への割り当てを拒否する必要があることを除いて、CとC++で違いはありません。

于 2012-05-24T17:24:05.707 に答える
4

1)a == bであることが保証されていますか?

そうではない。アドレスを比較していて、それらが異なる場所を指している可能性があることに注意してください。ほとんどのスマートコンパイラは、この重複するリテラル定数をフォールドするため、ポインタは同等に比較される可能性がありますが、これも標準では保証されていません。

2)なぜa == cではないのですか?コンパイラは、それらが同じ文字列を参照していることを認識できるべきではありませんか?

ポインタを比較しようとしています。ポインタは異なるメモリ位置を指しています。そのようなポインタの内容を比較したとしても、それらは依然として等しくありません(次の質問を参照)。

3)すでに\ 0が含まれている場合でも、cの最後に追加の\ 0が追加されていますか?

はいあります。

于 2012-05-24T17:25:17.020 に答える
3

最初に、文字列リテラルが減衰するものであるため、これは const char* である必要があることに注意してください。

  1. どちらも、「t」「e」「s」「t」の後に「\0」が続く配列を作成します (長さ = 5)。等しいかどうかを比較すると、両方が同じポインターで始まるかどうかだけがわかりますが、内容が同じかどうかはわかりません (論理的には、2 つのアイデアは互いに続きます)。
  2. a = 't' 'e' 's' 't' '\0' および b = 't' 'e' 's' 't' '\0' という同じ規則が適用されるため、A は C と等しくありません。 '\0'
  3. はい、コンパイラは常にそれを行います。このような文字列を作成している場合は、明示的に行うべきではありません。ただし、配列を作成して手動で入力した場合は、\0.

私の #3 では、 const char[] = "Hello World" も最後に \0 を自動的に取得することに注意してください。配列を手動で埋めることを参照していました。

于 2012-05-24T17:28:21.663 に答える
2

ここでの問題は、ポインタとテキストの同等性の概念を混合していることです。

あなたが言うとき、a == bまたはa == cあなたが関係するポインタが同じ物理アドレスを指しているかどうかを尋ねているとき。テストは、ポインタのテキストの内容とは何の関係もありません。

テキストの同等性を取得するには、次を使用する必要がありますstrcmp

于 2012-05-24T17:24:51.663 に答える
0

a!= b、b!= c、およびc!=aよりもポインタ比較を行っている場合。コンパイラが最初の2つの文字列が同じであることに気付くほど賢くない場合を除きます。

strcmp(str、str)を実行すると、すべての文字列が一致として返されます。

コンパイラがcにnull終端を追加するかどうかはわかりませんが、追加されると思います。

于 2012-05-24T17:25:32.973 に答える
0

他の回答で何度か言われたように、ポインタを比較しています。ただし、strcmp(b,c)最初の\0.

于 2012-05-24T17:33:25.010 に答える