1

私は何か面白いことをする小さなコードを持っていますが、それがどのように行われるのか理解できません。

int main(int argc, const char * argv[])
{
    char text[] = "object";
    for(char *ptr = &text[0]; *ptr != '\0'; ptr+=2) 
    {   
        cout << ptr << endl;
        ptr--;
    }
    return 0;
}

何が起こっているのかというと、[1]、[2]、[3]などから、毎回文字列の最後までコンテンツが出力されます。ポインタが逆参照されることはないので、それがどのように行われるのか理解できませんが、正しい文字が印刷されるようです。文字列の文字の代わりに、ポインタ値が奇妙な文字として出力されると思いますが、それは実際には起こりません。

4

3 に答える 3

3

これは未定義の動作です。最初の反復は、ptrを指し"object"ます。大丈夫です、それを出力しますが、あなたはptr--. だから今、ptrあなたがもはや所有していない記憶を指します。逆参照したり、ポインター演算を実行したりしない限り、問題ありません。しかし、ループ内でインクリメントするときはそうします - ptr+=2

なぜこのように振る舞うのですか:

最初の反復で、 がptrを指して"object"いるので、それを出力します。cout::operator << (const char*)null で終わる文字列を出力します。char逆参照は必要ありません。

2 番目の反復で、ptrが減分されてから だけ増加し2、 を指し"bject"ます。等々...

于 2012-05-24T20:01:15.547 に答える
2

そうです、通常は住所が印刷されます。ただし、 には特別なオーバーロードがchar *あります。これは、それを C 文字列と見なし、 から始まりptrゼロ ( ) が見つかるまで、すべての文字を出力し\0ます。

...または、コードが正しかった場合はptr、最初の反復で UB をデクリメント (ptr範囲外に移動) し、直後に 2 ずつインクリメントして UB を呼び出すため、これが発生します。


ポインターのアドレスを表示する場合は、次のようにキャストしますvoid *

cout << static_cast<void *>(ptr) << endl;
于 2012-05-24T20:00:23.107 に答える
2

ここでは本当にハッキーなことは何もありません。ostream::operator<<(const char *p)文字列を出力するがあります。ポインタは文字列に沿って移動し、プログラムはさまざまな位置から開始して出力します。唯一の奇妙な点は、クレイジーな +2、-1 ポインターのインクリメントです。

于 2012-05-24T20:01:00.243 に答える