2012-02-07 4 views
2
for(int i=0;i<10;i++) 
{ 
    cout << i+"passs" << "\n"; 
} 

C++でこの出力を与えるん:なぜ、このint型と文字列の連結は、次のようにこれは出力を生成し

passs 
asss 
sss 
ss 
s 

今、私の考えでは、我々はカウンタiがpasssに追加されますポインタ操作を見ているということです私たちは "passs"ポインタ+ 0、 "passs" pointer + 1などからの出力を見ています。

質問ヌル文字に達したときにそれが止まらない理由について、5つの空白行を表示します。

次はcout << "passs"+i << "\n";と同じものを印刷します。私はパスのポインタがおそらく最後の位置から来たはずだったので、これが2番目の位置からすべての空白行を出力したはずだと思いました。私がここに書いたものを読んで、それはおそらく第2のcoutのための出力は、それが方法であることを確認することが理にかなっています。

私は正しく考えているのか、これ以上私が理解していないことがあるのか​​知りたかったのですか?

+0

あなたが気づいたように、それは「連結」ではありません。だから、質問のタイトルはあなたが実際よりももっと混乱して見えるようになります;-) –

+0

@スティーブ・ロール、正しく言わなければならないでしょう – gizgok

答えて

2

あなたの最初の推論は正しいです。ここでポインタ演算をしているので、出力の最初の6行(6番目は\0\n)が良いです。しかし、あなたが弦の終わりを去るとき、あなたは困ってしまいます。あなたのfor-loopには反復を止めるものは何もないので、あなたのプログラムは理論的には"passs" + 6,7,8,9で何でもできます。

文字列リテラルは、タイプがconst char *であることを思い出してください。コンパイラによって決定され、メモリ内のいくつかの場所では、あなたが持っている:

| p | a | s | s | s | \0 | * | * | * | * | 

*シンボルは、あなたの文字列の末尾過去の不確定メモリの無男の土地を表します。あなたのfor-loopが実行されるとき、それはpで始まり、前方に歩いて行きます。 const char *を処理しているので、各ステップは1バイトになります。各ステップで、coutは、(出力に表示されているように)ヌル文字に達するまでできるだけ多く印刷を試みます。しかし、あなたは無人島から何かを印刷しようとすることは許されません。その結果、の定義されていない動作が発生します。あなたの場合、そのメモリには印刷できない文字が含まれています。

要約すると、大体正しいものでした。 coutがnullに達した時点で印刷を停止しました。しかし、for-loopはそうではありませんでした。

+0

"あなたは人間の土地から何も印刷しようとしていません。 " - 単に*ポインタを作成すると、未定義の動作になります。これの動機は、(1) '' passs ''のためのメモリがちょうどアドレス空間の最後にあるかもしれないので、それに6を加えるとオーバーフローが起こり、(2)C++がポインタのオーバーフローによるハードウェア障害(符号なしのint型のオーバーフローではなく、ラップアラウンドする必要があります)が発生する古くからの独自のアーキテクチャしたがって、 '6 +' passs ''はあなたがそれを印刷するかどうかにかかわらずUBです。 –

+0

私は、標準ライブラリアルゴリズムをサポートするために、あなたが1つの終わりを解決できることを保証されていると思いました。だから、この場合+6へのポインタを持つことはOKですが、+7から+9はそうではありません。とにかく、これは良い点です。持ち上げてくれてありがとう。 –

+0

申し訳ありませんが、あなたが正しいです、私はコメントの2つの場所で6の代わりに7を言ったはずです。あなたが言うように、質問者のループ内の「最初の」UBは「6 +」合格を逆参照しています。 「次の」UBは「7 +」パス「」を計算しています。 –

2

リテラル文字列はポインタ(ポインタ演算)として扱われるためにです:ポインタに整数を追加すると、前方にポインタを移動します。

"passs" + 1 = "asss" 
"passs" + 2 = "sss" 
"passs" + 3 = "ss" 

あなたが使用する必要がある文字列として番号を追加する:

cout << i << "passs" << "\n"; 
2

正しいですが、pointer + integerinteger + pointerの両方がポインタ演算を行い、新しいポインタを与え、出力は「正常」です。

4

あなたはそうです。

文字列リテラルは、文字列の先頭を指すポインタとして解釈されます。これにintを追加するのはポインタの増分です。

最後を過ぎると、未定義の動作になります。システムにはほとんど無害ですが、他のコアダンプで終了する可能性があります。

関連する問題