void main() {
if("a" == "a")
printf("Yes, equal");
else
printf("No, not equal");
}
なぜ出力No, not equal
ですか?
void main() {
if("a" == "a")
printf("Yes, equal");
else
printf("No, not equal");
}
なぜ出力No, not equal
ですか?
回答:
比較しているのは、異なる場所に格納されている異なる文字列の2つのメモリアドレスです。そうすることは基本的に次のようになります。
if(0x00403064 == 0x002D316A) // Two memory locations
{
printf("Yes, equal");
}
次のコードを使用して、2つの文字列値を比較します。
#include <string.h>
...
if(strcmp("a", "a") == 0)
{
// Equal
}
さらに、"a" == "a"
コンパイラーによっては、実際にtrueを返す場合があります。コンパイラーは、スペースを節約するために、コンパイル時に等しい文字列を1つに結合する場合があります。
2つの文字値(ポインターではない)を比較する場合、それは数値比較です。例えば:
'a' == 'a' // always true
-fmerge-constants
し、-fno-merge-constants
いくつかのGCCの上一定のマージは関係なく、常にそのオプションの有効化されているようですが、有効にする/無効にする文字列と翻訳単位間でのマージ浮動小数点定数を。
int
型を持っています。:-)また、ポインタは数値である必要はありません。
int
数値でもありませんか?しかし、文字はバイトだと思いました。Intは4バイトです。ポインタ自体も整数です。それらには、一連のデータ(実際に数値である必要はないデータ)のアドレスが含まれています。
'a' == 'A' // not true
... MySQLは異なることを頼みます。
パーティーには少し遅れますが、とにかく返事をします。技術的には同じビットですが、少し異なる観点から(以下のCの用語):
Cでは、式"a"
は文字列リテラルを示します。これは、名前のない静的な配列でconst char
、長さは2です。配列は文字'a'
で構成され'\0'
、終端のnull文字は文字列の終わりを示します。
ただし、Cでは、配列を値で関数に渡すことができないのと同じように、または(初期化後に)配列に値を割り当てることができません。配列にはオーバーロードされた演算子がない==
ため、直接比較することはできません。検討する
int a1[] = {1, 2, 3};
int a2[] = {3, 4, 5};
a1 == a2 // is this meaningful? Yes and no; it *does* compare the arrays for
// "identity", but not for their values. In this case the result
// is always false, because the arrays (a1 and a2) are distinct objects
それが==
配列を比較していない場合、それは実際には何をしますか?Cでは、ほとんどすべてのコンテキスト(これを含む)で、配列は(配列の最初の要素を指す)ポインターに減衰し、ポインターが等しいかどうかを比較すると、期待どおりの結果になります。これを行うと、効果的に
"a" == "a"
名前のない2つの配列の最初の文字のアドレスを実際に比較しています。C標準によれば、比較の結果はtrueまたはfalse(つまり1または0)になる"a"
可能性があります-sは実際には同じ配列または2つの完全に無関係な配列を表す場合があります。技術的な面では、結果の値は不定(すなわち、それはありません比較が許可されていることを意味し、未定義の動作や構文エラー)が、いずれかの値が有効であると実装(コンパイラ)は、実際に何が起こるかの文書には必要ありません。
他の人が指摘したように、「c文字列」(つまり、ヌル文字で終了する文字列)を比較するにはstrcmp
、標準ヘッダーファイルにある便利な関数を使用しますstring.h
。関数には、0
等しい文字列の戻り値があります。戻り値を明示的に比較することは良い習慣と考えられています0
演算子 `! 'を使用代わりに勧めします。つまり、
strcmp(str1, str2) == 0 // instead of !strcmp(str1, str2)
C99によると(セクション6.4.5 / 6)
文字列リテラル
これらの配列が異なるかどうかは、その要素が適切な値を持っているかどうかは不明です。
したがって、この場合、両方"a"
のが異なるかどうかは不明です。最適化されたコンパイラーは単一"a"
を読み取り専用の場所に保持し、両方の参照がそれを参照する可能性があります。
ここでgccの出力を確認してください
それらは2つの独立したconst char*
のポインタであるため、実際の値はありません。0x019181217 == 0x0089178216
もちろん、NOを返すようなものを言っている
のstrcmp()
代わりに使用==
ポインタ。
最初 "a"
は、ヌルで終了するASCII文字列へのポインタです。
二番目 "a"
は、ヌルで終わる別のASCII文字列へのポインタです。
あなたは32ビットコンパイラを使用している場合、私は期待したいです"a"=="a"-4
。私はちょうどかかわらず、TCC / Win32のでそれを試してみた、と私は得ます"a"=="a"-2
。しかたがない...
strcmp
数バイトを実行できる場合があります。一部のコンパイラはそれを実行し、一部は実行せず、一部は最小値より長い文字列に対してのみ実行します...
この質問は、すべての初心者に非常に良い説明の足跡を残します。
私もそれに貢献してみましょう.....
上記の誰もがについて説明したように、なぜそのような出力を得るのですか?
今あなたがあなたのPROGが欲しいなら。「はい」と印刷するには
どちらかを使用
if(strcmp("a", "a") == 0)
{
}
または
「a」を文字列として使用せずに、文字として使用します...
if('a'=='a')
{
printf ("yes Equal");
}
Cの文字は1バイトの短整数です。
'a'
は実際には整数です。
一部のコンパイラには、すべての定数文字列に同じアドレスを強制するために使用できる「文字列のマージ」オプションがあります。それを使用する場合は、に"a" == "a"
なりますtrue
。
この男は変数を使用しません。その代わり、彼は一時的にテキストアレイを使用していますa
とa
。理由
void main()
{
if("a" == "a")
printf("Yes, equal");
else
printf("No, not equal");
}
もちろん機能しません。変数を比較しないということです。
次のような変数を作成する場合:
char * text = "a";
char * text2 = "a";
あなたは、比較可能性text
とtext2
、それがあるべき真
多分あなたは使用すること{
を忘れないでください}
=)
void main() {
if("a" == "a")
{
printf("Yes, equal");
}
else
{
printf("No, not equal");
}
}
void main
??? ええと...