2017-07-07 121 views
-5

当我运行该程序时,它会打印变量a的值。但是当我评论该行'cout<<&b<<endl<<&a<<endl;'时,它会打印一个垃圾值。 背后有什么可以解释的?cout value without touch variable C++

#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'作为数组并且在数组中打印第二个*值。这超出了'pb'指向的范围,并导致*未定义的行为*。未定义的行为会导致您的整个程序*不合格*并且无效。 –

回答

0

当您打印ab的地址时,会强制变量实际具有内存地址。否则,一个值可能被存储在一个寄存器中,或者如果从未使用过,则根本不存在。

这是一种很常见的优化编译器进行改造

const int a = 9; 
cout << a; 

cout << 9; 

,从不存储a任何地方。

无论如何,没有规则说明变量要存储在内存中的位置和顺序。这完全取决于编译器。所以你的假设是​​(或&b - 1)是无效的。

-1

屏幕上的垃圾值是a和b的地址。你应该试试这个:

int *pb = &b; 
+0

你说得对,这个'cout <<&b << endl <<&a << endl;'会打印'a'和'b'的地址,但是无论你想用这个“答案”来实现什么,只会产生编译器错误。 – muXXmit2X

+0

Acc。对于这个问题,人们只是在询问其背后的解释,而不是询问任何错误! – Piyush

+0

_你应该试试这个:'int * pb - >&b;'_ 你在暗示什么是无效的语法,并且会产生编译错误!顺便说一句。我甚至不确定你在那里试图建议什么。 – muXXmit2X

0

有两个点在那里你可以得到“胡言乱语”的价值观但是其中只有一个是actualy其中垃圾被打印出来。

这个cout << &b << endl << &a << endl;将通过使用操作符地址打印地址ab。你看到的不是ab的值,而是存储在内存中的位置。这些是十六进制值,每次运行程序时它们可能都会更改。这是预期的行为。

然后有这个构造:*(pb + 1)这实际上是调用未定义的行为。但为什么呢?首先pb是一个指针,所以它存储一个地址,更具体地说是存储地址b。您可以直接打印出pb,这会得到与cout << &b相同的结果,也可以使用取消引用运算符*对其进行解引用。所以这cout << *pb将打印的值不是地址pb指向(10 btw)。现在你的声明有什么问题 - (pb + 1)是不是增加值pb是指向但地址保存在pb。因此它不再指向b的值,而是指向内存中的某个其他值。然后你解引用这个地址并读取一些随机值 - 这是你的“垃圾”值。

你可能想要的是增加pb指向的值。所以cout << (*pb + 1)将打印11(注意括号放置在哪里)。但cout << b仍然会导致10。如果你想真正改变的B您可以做到这一点的价值:

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

现在b增加了一个不接触b本身。