20
int main (int argc, **argv)
{
       if (argv[1] == "-hello")
            printf("True\n");
       else
            printf("False\n");
}
#。/ myProg -hello
誤り

なんで?戻り値がtrueであることに気付きstrcmp(argv[1], "-hello") == 0ました...しかし、2つのC文字列を比較するために等式演算子を使用できないのはなぜですか?

4

9 に答える 9

21

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

于 2010-10-14T13:30:38.230 に答える
17

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

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

于 2010-10-14T13:31:37.027 に答える
14

なぜなら、ほとんどのコンテキストではC、配列は「最初の要素へのポインタに崩壊する」からです。

したがって、配列が"foobar"あり、ほとんどのコンテキストでそれを使用すると、それはポインタに減衰します。

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

配列の内容何かと比較したいもの。あなたはそれを手動で行うことができます

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" */;
于 2010-10-14T13:36:19.077 に答える
6

Cストリングのようなものがないからです。

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

更新:「C文字列なし」とは、Cに文字列がないことを意味します。通常、「C文字列」と呼ばれるものは言語に依存しません(「パスカル文字列」のように)。これは、文字列をnullとして表現したものです。 -文字の終端線形配列。

于 2010-10-14T13:30:48.283 に答える
5

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

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

だからあなたが書くとき

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

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

strcmp()これが、文字列値を比較する ようなライブラリ関数を使用する必要がある理由です。

于 2010-10-14T16:54:05.873 に答える
3

C文字列自体は存在しないためです。それらはで終わるchar配列\0です。

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

一方、ゼロ以外を返す"-hello" == "-hello" 場合==がありますが、それは演算子が字句的に比較することを意味するものではありません。それは他の事実によるものです。

字句的に比較したい場合は、いつでもできます

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

よく読んでくださいあなたはc++としてタグ付けされているようです。だからあなたは

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

 if (arg1 == "-hello"){
    // yeahh!!!
 }
 else{
    //awwwww
 }
于 2010-10-14T13:31:02.323 に答える
2

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

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

于 2010-10-14T13:31:21.397 に答える
1

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

于 2010-10-14T13:31:54.433 に答える
0

C文字列は文字の配列だからです。配列は、配列の最初の要素への単なるポインタであり、==を使用して2つのポインタを比較すると、それらが指す値ではなく、それらが指すメモリアドレスを比較します。

于 2010-10-14T13:31:12.270 に答える