3

配列を処理するときにポインターの使用を実験していたところ、C++が配列を処理する方法に少し混乱しました。これが私が書いたコードの関連する部分です:

//declare a string (as a pointer)
char* szString = "Randy";               

cout << "Display string using a pointer: ";
char* pszString = szString;
while (*pszString)
cout << *pszString++;

まず、coutを使用して「pszString」にあるものを(参照を解除せずに)書き込もうとしたとき、文字列が表示されるのを見て少し驚きました。ポインタに変数ではなく文字列を指定したためだと思いました。

しかし、本当に私の注意を引いたのは、行からアスタリスクを削除すると、cout << *pszString++;「Randyandyndydyy」と印刷されたことです。なぜ配列を書き込んだ後、1​​文字少なくして再度書き込むのかわかりません。私の推論は、char文字列を書き込んだ後、インクリメント演算子は、nullターミネータに到達する前に、インデックスをすぐに次の文字に移動するというものです。文字列が初めて出力された後、nullターミネータがループにfalseを返さない理由がわかりません。これは正しい理由ですか?配列とポインタの間にこの関係があるかどうか誰かが説明できますか?

4

1 に答える 1

6

cout文字列全体を印刷するためのoperator<<オーバーロードchar*があります(つまり、に遭遇するまで各文字を印刷します0)。対照的に、のオーバーcharロードはその1文字だけを出力します。それが本質的にここでの違いです。さらに説明が必要な場合は、読み進めてください。coutoperator<<

ポインタをインクリメントした後で間接参照すると、とではなく、が送信さcoutれるため、1文字が出力されます。charchar*

だからcout << *pszString++;_

cout << *pszString;
pszString = pszString + 1;

ポインターを逆参照しない場合は、ポインターを送信するchar*ためcout、文字列全体が印刷され、ループの各反復で文字列の先頭が1文字上に移動します。

だからcout << pszString++;_

cout << pszString;
pszString = pszString + 1;


小さなループ展開の図:

にとってcout << *pszString++;

Randy\0
^ pszString points here

// this means increment pszString and send cout the character at which pszString *used* to be pointing
cout << *pszString++;

// so cout prints R and pszString now points
Randy\0
 ^ here

// this means increment pszString and send cout the character at which pszString *used* to be pointing
cout << *pszString++;

// so cout prints a and pszString now points
Randy\0
  ^ here

// and so on

にとってcout << pszString++;

Randy\0
^ pszString points here

// this means increment pszString and pass the old pointer to cout's operator<<
cout << pszString++;

// so cout prints Randy, and now pszString points
Randy\0
 ^ here

cout << pszString++;

// cout prints andy, and now pszString points
Randy\0
  ^ here

// and so on

この方法でポインターを実験していることをうれしく思います。ポインターを処理する必要がないようにするために何かをする多くのプログラマーとは異なり、実際に何が起こっているのかを知ることができます。

于 2011-08-19T19:31:32.770 に答える