2017-11-02 11 views
2

以下の特定のコードのロジックをフォローする際に問題があります。ポインタの算術ポスト/プリフィックスのインクリメント

int i[] = { 21, 4, -17, 45 }; 

int* i_ptr = i; 

std::cout << (*i_ptr)++ << std::endl; // 21 

std::cout << *i_ptr << std::endl;  // 22 

std::cout << *i_ptr++ << std::endl;  // 22 

std::cout << *(i_ptr - 1) << std::endl; // 22 

std::cout << *i_ptr << std::endl;  // 4 

std::cout << ++*i_ptr << std::endl;  // 5 

std::cout << *++i_ptr << std::endl;  // -17 

system("pause"); 

私の問題は、5

std::cout << ++*i_ptr << std::endl;  // 5 

std::cout << *(i_ptr - 1) << std::endl; // 22 
4に

std::cout << *i_ptr << std::endl;  // 4 

そして...このコードのビットが22から行ったのですか

このコードを最初に読んだとき、私は22がjusだと思った私はそれがC++演算子の優先順位と関係していることを理解していますが、これは私には意味がありません。

答えて

5
std::cout << (*i_ptr)++ << std::endl; // 21 
//i_ptr points to i[0], which is increased from 21 to 22 

std::cout << *i_ptr << std::endl;  // 22 
//prints i[0], which is 22 

std::cout << *i_ptr++ << std::endl;  // 22 
//prints i[0] and increments i_ptr to point to i[1] 

std::cout << *(i_ptr - 1) << std::endl; // 22 
//prints i[0], i_ptr points to i[1], so i_ptr - 1 points to i[0] 

std::cout << *i_ptr << std::endl;  // 4 
//prints i[1], which is 4 

std::cout << ++*i_ptr << std::endl;  // 5 
//prints the incremented i[1], which was 4 and is 5 now 

std::cout << *++i_ptr << std::endl;  // -17 
//increment i_ptr to point to i[2] and prints the value 
+0

OH!私はダムです。助けてくれてありがとう! :) – 73memedream

1

*i_ptr++は、ポインタをインクリメントします。これは、配列のの2番目の要素(値4)を指し示します。

もちろん、i_ptr - 1は、最初に22の値を持つi_ptrが指し示す前の要素を指していなければなりません。

と覚えては、任意のポインタや配列pとインデックスiのために、表現p[i]*(p + 1)は正確に同じです。これは最初の

 
+-----+-----+-----+-----+ 
| 22 | 4 | -17 | 45 | 
+-----+-----+-----+-----+ 
^ 
| 
i_ptr 

次にあなたが*i_ptr++の操作を行います。あなたはあなたが、その後i_ptrが指している値をインクリメント(*i_ptr)++

 
+-----+-----+-----+-----+ 
| 21 | 4 | -17 | 45 | 
+-----+-----+-----+-----+ 
^ 
| 
i_ptr 

でスタート

それを見るために

もう一つの方法は、 古い値の値をi_ptrと逆参照します(結果はとなります)。)、その後増分ポインタ:

 
+-----+-----+-----+-----+ 
| 22 | 4 | -17 | 45 | 
+-----+-----+-----+-----+ 
    ^
     | 
     i_ptr 

そして今、あなたは基本的にi_ptr[-1]行います

 
+-----+-----+-----+-----+ 
| 22 | 4 | -17 | 45 | 
+-----+-----+-----+-----+ 
^ ^
|  | 
|  i_ptr 
| 
i_ptr - 1 

負のインデックスがある限り、彼らは外出しないよう、大丈夫と明確に定義されました範囲の。

std::cout << *i_ptr++ << std::endl;  // 22 

i_ptrポイント4に、この行の後にすでに

0

。したがって、次の行に再度22を取得する前に、あなたは一つの要素を印刷するとき:

std::cout << *(i_ptr - 1) << std::endl; // 22 

、今i_ptrはまだ4を指す:

std::cout << *i_ptr << std::endl;  // 4 
0

これは、これら三つのラインに関係しています:

std::cout << *i_ptr++ << std::endl;  // 22 
std::court << *(i_ptr - 1) << std::endl; // 22 
std::cout << *i_ptr << std::endl;  // 4 

ここではどうなりますか:

ここ
std::cout << *i_ptr++ << std::endl;  // 22 

、これが意味する*(i_ptr++)として解釈される「i_ptrを指してするために使用される場合に、そのderferenceポインタを手の甲次いで、次の要素を指すように前方事前PTR」を換言すれば、この後行の実行が終了すると、ポインタptrは要素4を指していますが、ptrが指し示していた場所であるため、行は22を出力します。これは出力がすぐにこれを示唆していなくても、我々が見ている場所を変更したことを意味するので重要です。

はのは、次の行を見てみましょう:

のstd :: coutを< < *(i_ptr - 1)< <はstd ::てendl; // 22

これは、「i_ptrが探している場所の1つ前の要素を出力します」というメッセージです。この時点で、i_ptrは4を見ているので、リストの1つの要素を調べると値22 。

最後に、我々はこれを行う: - としばらくしている - それは我々がここで見るものだ

std::cout << *i_ptr << std::endl;  // 4 

をこれは、我々は4を見ているので「見ているものは何でもi_ptrプリントアウト」と言います。