12


3

等価演算子==を使用して、2つの文字列をCで等価かどうかを比較します
int main (int argc, **argv)
{
       if (argv[1] == "-hello")
            printf("True\n");
       else
            printf("False\n");
}
# ./myProg -hello
False

Why? 私は `strcmp(argv [1]、" -hello ")== 0`がtrueを返すことを理解しています…​ しかし、なぜ等価演算子を使用して2つのC文字列を比較できないのですか?

9 Answer


16


(たとえば) `argv [1]`は実際には文字列へのポインタであるためです。 あなたがしているのは、ポインタを比較することだけです。


12


Cコンパイラには文字列リテラル以外の文字列についての手がかりがないため、Cの文字列を==と比較することはできません。

コンパイラーは、どちらかの側で `char *`との比較を確認するため、ポインター比較(ポインターに格納されているアドレスを比較します)を行います


11


  • C *では、ほとんどのコンテキストで、配列は「最初の要素へのポインタに減衰する」ためです。

したがって、配列 "" foobar "`があり、ほとんどのコンテキストで使用すると、ポインターになります。

if (name == "foobar") /* ... */; /* comparing name with a pointer */

配列の内容と_something_を比較するもの。 手動でできます

if ('p' == *("foobar")) /* ... */; /* false: 'p' != 'f' */
if ('m' == *("foobar"+1)) /* ... */; /* false: 'm' != 'o' */
if ('g' == *("foobar"+2)) /* ... */; /* false: 'g' != 'o' */

または自動的に

if (strcmp(name, "foobar")) /* name is not "foobar" */;


7


C文字列のようなものはないからです。

Cでは、文字列は通常、charの配列、またはcharへのポインター(ほぼ同じ)です。 ポインター/配列をconst配列と比較しても、期待される結果は得られません。

更新:「Cストリングなし」とは、Cにストリングがないことを意味します。 通常「C文字列」と呼ばれるものは言語に依存せず(「パスカル文字列」と同様)、文字列のヌル終了線形配列としての文字列の表現です。


5


Cでは、文字列値(文字列リテラルを含む)は、 char`の後に0ターミネータが続く配列として表されます。==`演算子を使用して配列の内容を比較することはできません。言語は単に操作を定義しません。

sizeof`または& `演算子のオペランドである場合、または宣言内の別の配列を初期化するために使用される文字列リテラルである場合を除き、「TのN要素配列」型の式は暗黙的に変換(減衰)して「Tへのポインター」を入力すると、式の値は配列の最初の要素のアドレスになります。

だからあなたが書くとき

if (argv[1] == "-hello")

コンパイラは、暗黙的に式「 "-hello"」を「7要素のchar配列」から「charへのポインター」に変換し(「argv [1]」は既にポインター型です)、式の値は文字「 '-'」の_アドレス_。 ですから、 `==`が比較すると、2つの_pointer_値が得られます。これは、「 "-hello"」と「argv [1]」(ほとんどの場合)がメモリ内の異なる領域を占めるため、等しくなることはありません。

これが、文字列値を比較するために `strcmp()`のようなライブラリ関数を使用しなければならない理由です。


3


C文字列はそのように存在しないからです。 これらは、 `\ 0`で終わるchar配列です。

等価演算子 `==`は、配列の最初の要素へのポインターが同じであることをテストします。 辞書順に比較することはありません。

一方、 `" -hello "==" -hello "`は非ゼロを返す可能性がありますが、それは `==`演算子が辞書編集的に比較するという意味ではありません。 それは他の事実によるものです。

辞書編集を比較したい場合は、いつでもできます

#define STR_EQ(s1,s2)    \
   strcmp(s1,s2) == 0

もっと読むと、あなたがc ++とタグ付けしたことがわかります。 だからできる

 std::string arg1 ( argv[1] );

 if (arg1 == "-hello"){
    // yeahh!!!
 }
 else{
    //awwwww
 }


2


文字列はCのネイティブ型ではありません。 この例で比較しているのは、2つのポインターです。 1つは最初の引数で、もう1つは「-hello」の内容を持つ静的な文字配列です。

あなたは本当にstrncmpまたは同様のものを使いたいです。


1


==を使用している場合、ポインターを比較しています。 つまり、2つのオペランドがメモリ内の同じ文字列を参照する場合、trueを返します。 したがって、文字列を辞書式に比較する際に使用するには適していません。


-1


C文字列は文字の配列であるためです。 配列は、配列の最初の要素への単なるポインターであり、2つのポインターを比較する場合は == それが指す値ではなく、それらが指すメモリアドレスを比較します 彼らは指します。