0

関数の奇妙な動作を理解してstrcmpいます。これは、次のコードで示されます。

#include <iostream> 
#include <cstring>

using namespace std;

int main()
{
    char *p = "no";

    cout << p << endl;                      //Output: no
    cout << &p << endl;                     //Output: 0x28ac64
    cout << strlen(p) << endl;              //Output: 2
    cout << strcmp(p, "no") << endl;        //Output: 0

    cin >> p;                               //Input: bo

    cout << p << endl;                      //Output: bo
    cout << &p << endl;                     //Output: 0x28ac64
    cout << strlen(p) << endl;              //Output: 2

    cout << strcmp(p, "no") << endl;        //Output: 0
    return 0;
}

私が理解できないのは、行 15 の出力が 0 である理由です。0 は 2 つの文字列が等しいことを意味しますが、明らかにそうではありません。ここで何が欠けていますか?

PSヘッダーにエスケープ文字が含まれていることをお詫びしますが、削除するとiostreamを表示できませんでした。これを投稿していますが、次回は正しくする方法を見つけます。:)

4

3 に答える 3

6

問題はp、文字列リテラルを指しているため、文字列リテラルを変更しようとすると、cin >> p;未定義の動作が直接発生することです。

最も可能性が高いのは、コンパイラが文字列リテラルを定数として扱っているため (変更する必要がないため)、(コンパイル時に) 結果がどうあるstrcmpべきかを判断し、それを生成することです。実行時に変更するという事実は無視されます。とにかくそれを行うことは想定されていないからです。

于 2013-03-03T04:43:36.387 に答える
3

残念ながら、互換性のために多くのコンパイラがこれをサポートしています:

char *p = "no";

コンパイルと修正に失敗するのは次のとおりです。

const char *p = "no";

これを修正すると (少なくとも警告が表示されるはずです)、次のコンパイル エラーで何が問題なのかがわかります。

于 2013-03-03T04:45:20.880 に答える
1

pの配列の最初の要素を指していconst charます。これらの値を ( で行うようにcin >> p) 変更しようとすると、未定義の動作が発生します。

于 2013-03-03T04:43:38.237 に答える