【问题标题】:C++ for variable scope用于变量范围的 C++
【发布时间】:2012-12-28 10:55:43
【问题描述】:

我是 C++ 新手,遇到了这个问题:

    for (int i=0 ; i<500 ; i++) {
        //to do
    }

    int i;
    std::cin >> i;

更新:使用 Visual Studio 2010(及其使用的编译器)for 循环外的 i 在调用 cin >> i 之后的值为 500;我正在使用 Visual Studio 调试器查看值

现在我期待

a) 整数 i;在 for 循环和 int i=0 之外;成为不同的变量,即 for 循环 i 一旦大括号关闭就会超出范围

b) 一旦我意识到它没有超出范围,我想知道为什么它没有被 cin 覆盖。

我认为 b) 是故意的(尽管我在 Bjarne Stroustrup 关于 c++ 的书中找不到它所在的页面),但我确信它在同一本书中指出变量在它们所包含的大括号内具有范围。

在我知道的大多数其他语言中,当在 for 构造中声明变量时,它们被认为位于 for 循环的大括号中,但在 c++ 中似乎并非如此。

是这种情况吗,这是否特定于 for 循环,或者是否有其他情况发生这种情况(我想不出任何其他情况,但嘿,我是新人)

谢谢

【问题讨论】:

  • 是什么让您相信它不会超出范围? for循环中的i只在for循环中有效。
  • 除非您使用的是旧版 Microsoft 编译器,它没有正确实现规范。
  • @GregHewgill,对,我想我对那件事有微弱的记忆。你确认了。
  • 无论我在控制台输入什么,我都在使用 Visual Studio 2010 编译器和 cin>>i == 500 之后的 i 变量
  • 你怎么看i的值是多少?您是在使用调试器,还是实际上用std::cout &lt;&lt; i 或其他东西打印值?如果您使用的是调试器,请记住,您不能总是相信调试器告诉您的内容,尤其是当您在同一个函数中有两个不同的变量同名时。

标签: c++ visual-studio-2010 scope


【解决方案1】:

在某些情况下,尤其是当您在同一个函数中有两个同名的不同变量时,您不能总是相信调试器会为您提供正确的信息。如果您询问i 的值,调试器可能不知道您指的是哪个i。根据您的描述,听起来编译器为i 的每个不同实例分配了两个不同的内存位置。

我经常使用的原则如有疑问,请打印更多内容。如果您使用std::cout &lt;&lt; i,那么您应该会看到i实际 值,该值在您打印输出点的范围内。

【讨论】:

  • 感谢 Greg - 我一直希望调试器能够显示正确的变量,但现在可以看到为什么它不会出现在这种情况下。标记为答案并感谢您的帮助
【解决方案2】:

嗯,很多答案,甚至还有一个被选为“解决方案”。

但无论如何,Visual C++ 10.0(Visual Studio 2010 附带的编译器)的问题在于 它默认为它可以配置为预标准行为,其中声明了变量的范围在for 循环中扩展了循环所在的块。

你想要这个选项:

/Zc:forScope,wchar_t

它启用了标准 C++ for-scope 以及内置的 wchar_t 类型,你想要这个:

/GR

启用 RTTI(即 dynamic_casttypeid)。

为了尽可能标准,您还需要此链接器选项:

/entry:mainCRTStartup

为 GUI 子系统程序启用 C++ 标准 main,当然您希望启用异常处理,但我记得对于默认启用的 Visual C++ 项目(尽管不是用于命令行编译器)。

当然,您还希望通过/W4 启用尽可能多的警告,尽管这与标准一致性无关。

但无论如何,总而言之,for 范围很奇怪的原因很可能是由于编译器和/或 Visual Studio 项目 defaulting 已设置为旧的预标准规则,并且选项是/Zc:forScope

【讨论】:

  • 虽然没有解决我遇到的问题(它基本上是调试器向我显示了错误的值,我确实检查了 /Zc:forScope 选项是否正确设置(默认))这实际上非常适合帮助新手(我)理解并正确设置,所以+1,谢谢
【解决方案3】:

假设一致性(并且不符合该点的编译器很可能会给出编译错误),您的两个 i 是不同的。但是没有什么能阻止编译器为两者使用相同的内存位置,因为它们的生存时间也是不同的,因此第二个i 从第一个的最终值开始,因为它没有被初始化,在这种情况下是可以预料的.

cin &gt;&gt; i 不允许您输入新值的事实与此无关。而且除了猜测原因之外,您没有提供足够的信息来做更多的事情(我的猜测是流处于错误状态)。

【讨论】:

  • 我已经重新测试,你看到的程序是“完整的”——它不会覆盖 i 但如果我将变量 outisde 更改为 j 调用 cin >> j 确实可以作为预计。
  • 您的程序不完整,无法编译。你怎么知道输入后i是500?如果是使用调试器,那么在其余的描述中,我的第一个赌注是编译器不使用相同的内存位置,并且调试器会混淆你想要哪个。
  • 该程序缺少它的主要功能 - 这是假定的,因为没有它显然不会是一个完整的程序。将我的代码放在“main”中,包含 std 命名空间,它将编译。
  • @PaulSullivan,我已经回答了太多问题,其中问题在于 OP 虽然显而易见,甚至不需要被质疑甚至没有说明。
  • 公平点 AProgrammer - 如果我遇到错误的方式,答案已经发布并道歉 - 我假设人们会意识到这是一个代码 sn-p 并暗示在 main 等。我想我高估了其他操作。无论如何感谢您的帮助:)
【解决方案4】:

我认为这是因为第二个 i 没有初始化,编译器对第二个 i 使用相同的内存块。 它们仍然是不同的两个变量。是的,第一个 i 被舀到循环中。 因此它是未定义的,你不能指望第二个 i 是 500。

for (int i=0 ; i<500 ; i++) {
    //to do
}

int i=0;  //  initialize i
std::cin >> i;

【讨论】:

  • 结果它按预期工作 - 只是调试器显示 i 具有相同的值,但 cout > i 之后确认未初始化和正确的值。无论如何谢谢:)
猜你喜欢
  • 2013-12-04
  • 2017-10-30
  • 1970-01-01
  • 2010-12-03
  • 2021-11-14
  • 2011-12-23
  • 2014-02-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多