2017-07-07 15 views
-1

私はC++を使い始めています。このコードスニペットで遊んでいる間に、別の 出力を理解したかったのです。ループとメモリ管理におけるC++ポインタ算術演算?

私はこのコードを実行すると、私は「私」であるPTRのdeferenced値 、ということを理解
int main() 
{ 
    int i = 3; 
    int *ptr = &i; //stores address of the i 
    while(*(ptr)--) //the same as i-- 
    { 
     cout << *ptr << endl; 
    } 
} 

、私はを使用する場合、「i」が0に等しい。しかしとき1は、ループを抜ける から差し引かれますwhile(* ptr--)の代わりにwhile(*(ptr) - )私は最終的に0になるランダムな整数のリストを取得し、ループが壊れます。私の理解へ

私は、各ループで& I(* PTR)の先頭アドレスからのバイト(1つのint型のサイズ)を引いています* ptr--を使用しています。しかし、なぜプログラムは最終的に終了するのですか? "i"の値が何であっても、プログラムは23個の乱数を出力し、最後の数字は0になり、ループは終了します。プログラムのメモリが不足しているため、オーバーフローエラーが発生しませんか?

ただし、を使用しているときに(ptr--)のプログラムは無限ループに入ります。 正確には何が起こっていますか?

ありがとうございました。

+0

ちょうどループが長いからといって、無限であるとは限りません。 – harold

+1

'* ptr - 'と '*(ptr) - 'はまったく同じです... –

答えて

2

(ptr)ptrと同じであり、従って(ptr)--ptr--と同じです。

*ptr--i--と同じではありません!

ポインタののには、operator--が適用されています。接尾辞/接尾辞operator--は、operator*よりもhigher precedenceです。したがって、*ptr--*(ptr--)と同じで、期待通りです。(*ptr)--ではありません。

IOW、ptr--は、現在のポインタコピーを返し、最初に評価取得し、ポインタをデクリメントし、次にあなたが以前が指していた値を取得するためにコピーポインタを逆参照されていますで。

これは、あなたがガベージを見ている理由です。あなたが属していないメモリにポインタを減らしています。

intではなくポインタを減らすには、代わりに(*ptr)--を使用します。

int main() 
{ 
    int i = 3; 
    int *ptr = &i; //stores address of the i 
    while((*ptr)--) //the same as i-- 
    { 
     cout << *ptr << endl; 
    } 
} 

Live demo

括弧と演算子の優先順位の問題:IOWは、まずポインタを逆参照し、例えば、で指摘されている値をデクリメント!

+1

以前の開発者からのファームウェアのバグに対処しなければならなかったのは、あまりにも過ぎているかもしれませんが、読者とコンパイラの両方に絶対に明快にするために、かっこを使用してください。 – M4rc