C++两次打电话
我正在编写一个代码,并意外地将int
在变量两次之前,并注意到最终产品中有所不同。
int main ()
{
int number = 123456789;
int step = 0;
while (number>0)
{
cout << number%10 << endl;
number = number/10;
step = step+1;
cout << "step ; " << step << endl;
}
return 0;
}
输出是:
9
step ; 1
8
step ; 2
7
step ; 3
6 ...
但是,当我以这种方式打电话时:
int main ()
{
int number = 123456789;
int step = 0;
while (number>0)
{
cout << number%10 << endl;
number = number/10;
int step = step+1;
cout << "step ; " << step << endl;
}
return 0;
}
输出突然更改为:
9
step ; 11006125
8
step ; 11006126
7
step ; 11006127
6
有人可以解释差异,以便下次我会想到吗?
I was writing a code, and accidentally put int
before a variable twice, and noticed something different in the end product.
int main ()
{
int number = 123456789;
int step = 0;
while (number>0)
{
cout << number%10 << endl;
number = number/10;
step = step+1;
cout << "step ; " << step << endl;
}
return 0;
}
The output was:
9
step ; 1
8
step ; 2
7
step ; 3
6 ...
However, when I called it this way:
int main ()
{
int number = 123456789;
int step = 0;
while (number>0)
{
cout << number%10 << endl;
number = number/10;
int step = step+1;
cout << "step ; " << step << endl;
}
return 0;
}
The output suddenly changed to:
9
step ; 11006125
8
step ; 11006126
7
step ; 11006127
6
Can someone please explain the difference, so that I will be mindful next time?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
C ++是块范围。当您重新列出
spep
中
loop(通过使用int step
而不是步骤
)时,您是“ Shadow “步骤
来自该范围的外部;当外部step
(具有值0
)仍然存在时,它无法直接从内部范围读取(用不同名称的指针/引用步骤
可以读取/写数据,您只是直接通过该名称直接读取ofterstep
)。外部
步骤
是看不见的,因此int step = step + 1;
将“请分配给本地step
在添加1
之后,存储在本地步骤
中(直到那一刻才存在,尚无定义值)。由于步骤
它读取的是垃圾,因此这是不确定的行为,在实践中,它会变成垃圾(无论您在输入时,碰巧在该位置都留在该位置上的垃圾,
)。内部
步骤
的第二个和后续创建仍然是未定义的行为,但是在这种情况下(在大多数情况下,不涉及循环的展开),编译器选择与他们重复使用相同的存储空间事先使用内部步骤
(该循环的迭代结束时,该>>过期)。因此,作为新的内部步骤
从与过期的内存位置阅读的巧合基地。但是,要清楚,所有这些都是不确定的行为。要感谢您没有鼻腔恶魔,而将来只使用第一种表格。我会注意,如果您启用所有警告,任何值得盐的编译器都应检测到此错误(整个错误都存在于单行的范围中);可悲的是,似乎至少GCC不值得盐,因为即使使用
- - wall -wextra -werror -pedantic
是您不使用 ofterstep
变量。如果使用或删除了外部step
的声明,没有任何警告, ,所以我想您只是记得不要以其自身的价值来初始化变量。C++ is block scoped. When you redeclare
step
inside thewhile
loop (by usingint step
instead of juststep
), you "shadow" thestep
from outside that scope; while the outerstep
(with value0
) still exists, it cannot be read directly from the inner scope (a pointer/reference to the outerstep
with a different name could read/write the data, you just can't read the outerstep
directly through that name).The outer
step
is invisible, soint step = step + 1;
translates as "please assign to the localstep
the value of whatever is already stored in the localstep
(which, not existing until that moment, has no defined value yet) after adding1
". Since thestep
it reads from is garbage, this is undefined behavior, and in practice, it gets garbage (whatever junk happened to be left on the stack in that position from before you entered thewhile
).The second and subsequent creations of the inner
step
are still undefined behavior, but in this case (and in most cases where loop unrolling isn't involved) the compiler chose to reuse the same storage for them as the prior use of innerstep
(that expired when that iteration of the loop ended). Thus, as a coincidence of the new innerstep
reading from the same memory location as the expired innerstep
, it increments normally from then on, based on the original garbage value as a base.But again, to be clear, all of this is undefined behavior. Be thankful you didn't get nasal demons, and only use the first form in the future. I'll note, if you enable all warnings, any compiler worth its salt should detect this error (the entire error exists in the scope of a single line); sadly, it appears at least GCC is not worth its salt, because the only thing it detects, even with
-Wall -Wextra -Werror -pedantic
is that you didn't use the outerstep
variable. If you used it, or deleted the declaration of the outerstep
, it compiles with no warnings, so I guess you're stuck just remembering not to initialize a variable in terms of its own value.在第二种情况下,您声明了第二个变量,该变量也称为
step
,但仅在循环内可见。In the second case, you declare a second variable, which is also called
step
, but is visible only inside the loop.