2017-07-07 8 views
-5

私はプログラムを実行すると、変数aの値を出力します。しかし、私が 'cout<<&b<<endl<<&a<<endl;'という行にコメントすると、ガベージ値が表示されます。 その背後にある説明は何でしょうか?変数Cに触れることなくcout値

#include<iostream> 
using namespace std; 

int main() 
{ 
    int a = 9; 
    int b = 10; 
    int *pb = &b; 
    cout<<&b<<endl<<&a<<endl; 
    cout<<*(pb+1); 
} 
+3

*未定義の動作* - '*(pb + 1);'は範囲外にアクセスします。 – UnholySheep

+0

これは未定義の動作です。そして、これは、 –

+3

との呼び出し規約で、 'pb'は* single *' int'変数を指しているからです。 '*(pb + 1)'を実行すると、 'pb [1]'と同じです。これは配列として 'pb'を使い、* second *値を配列に出力します。これは、 'pb'が指すものの範囲外であり、*未定義の動作*につながります。定義されていない動作は、あなたの全プログラムを不正な形式にして無効にします。 –

答えて

0

abのアドレスを印刷すると、実際に変数に実際にメモリアドレスが設定されます。さもなければ、値はレジスタに格納されるかもしれません、または決して使用されないなら全くありません。

これは、コンパイラが

cout << 9; 

const int a = 9; 
cout << a; 

を変換し、決してどこでもaを格納するための非常に一般的な最適化です。

とにかく、変数がどこでどのような順序でメモリに格納されるかを示すルールはありません。それは完全にコンパイラに任されています。したがって、あなたの前提は​​(または&b - 1)は無効です。

-1

画面上のガベージ値は、aとbのアドレスです。あなたはこの試してみてください:

int *pb = &b; 
+0

この 'cout <<&b << endl <<&a << endl;は' a'と 'b'のアドレスを表示しますが、あなたが達成しようとしていることは"コンパイラエラーだけを生成します。 – muXXmit2X

+0

Acc。その人はちょうど何かエラーを尋ねるのではなく、その背後にあるexplainationを求めている質問に! – Piyush

+0

これを試してください: 'int * pb - >&b;' _ 無効な構文があり、コンパイラエラーが発生するでしょうか? Btw。私はあなたがそこに示そうとしていることさえも知らない。 – muXXmit2X

0

をゴミがプリントアウトされた場合、それらの一方のみがactualyである、しかし、あなたは「ちんぷんかんぷん」の値を得ることができる2つのスポットがあります。

このcout << &b << endl << &a << endl;は、アドレス-operatorを使用してabのアドレスを出力します。あなたが見ているのは、abの値ではなく、メモリに格納されている場所です。それらは16進数値で、プログラムを実行するたびに変更されます。これは予想される動作です。

次に、このコンストラクトがあります:*(pb + 1)これは実際には未定義の動作を呼び出しています。しかし、なぜこれは?まずpbはポインタであるため、アドレス、具体的にはbが格納されているメモリアドレスを格納します。 pbを直接印刷すると、cout << &bと同じ結果になるか、または参照解除演算子*を使用して逆参照することができます。したがって、このcout << *pbは、アドレスpbが(10btw)を指していない値を印刷します。あなたの声明が間違っているところに - はpbの値を増やしていませんが、アドレスはpbに保存されています。したがって、それはもはやbの値を指すのではなく、メモリのどこかの他の値を指しています。次に、このアドレスを逆参照してランダムな値を読み込みます。これがあなたの "ゴミ"値です。

pbの値を大きくすることをお勧めします。したがって、cout << (*pb + 1)11(角括弧が配置されているところに注意)を印刷します。しかしcout << bはまだ10になります。あなたが実際にあなたがこれを行うことができますbの値に変更したい場合は:今すぐb

int b = 10; 
int *pb = &b; 
*pb += 1; 
cout << b; 

b自体に触れることなく1増加しました。

関連する問題