【问题标题】:What is the scope of a 'while' and 'for' loop?“while”和“for”循环的范围是什么?
【发布时间】:2011-10-24 19:13:32
【问题描述】:

whilefor 循环的范围是什么?

例如,如果我在循环中声明了一个对象,它的行为是什么,为什么?

【问题讨论】:

    标签: c++ c


    【解决方案1】:

    在以下示例中,除了i 之外,循环的每次迭代都会销毁并重新创建所有变量,i 在循环迭代之间持续存在并且可用于 for 循环中的条件表达式和最终表达式。在循环之外没有任何变量可用。在i 递增之前,for 循环体内的变量会被破坏。

    while(int a = foo()) {
        int b = a+1;
    }
    
    for(int i=0;
        i<10;     // conditional expression has access to i
        ++i)      // final expression has access to i
    {
        int j = 2*i;
    }
    

    至于为什么;循环实际上为它们的主体使用一个语句,只是碰巧有一个由花括号创建的称为复合语句的语句。在任何复合语句中创建的变量的范围仅限于复合语句本身。所以这确实不是循环的特殊规则。

    循环和选择语句对于作为循环或选择语句本身的一部分创建的变量确实有自己的规则。这些只是根据设计师认为最有用的东西设计的。

    【讨论】:

    • 是的,while 循环中的a 也会在每次迭代时创建和销毁。
    • 我不会说 /variable/ 被破坏了……只是它的值被重置了。从理论上讲,它应该在每次迭代中占用相同的内存位置,并且就 cpu 周期而言,没有创建或销毁任何东西的开销。
    • 根据 C++,对象实际上已被销毁。如果它是带有析构函数的对象,则调用析构函数。在发生的时间和在下一次迭代中创建对象之间,没有对象占用该内存。
    • @DuncanACoulter 注意到您正在查看的变量在与我描述为在每次迭代中创建和销毁的任何变量不同的位置声明。您看到的行为是正常的,而不是优化器的结果。
    • @bames53 所以你做到了,我完全忽略了你明确地说“除了 i”+1 以进行温和的纠正。
    【解决方案2】:

    在循环中声明的任何内容都限定在该循环范围内,并且不能在大括号之外访问。事实上,您甚至不需要循环来创建新范围。您可以执行以下操作:

    {
       int x = 1;
    }
    
    //x cannot be accessed here.
    

    【讨论】:

    • 不确定它怎么会是一个未知的技巧,甚至可能不会称之为技巧:) 这是一个非常糟糕的基本范围说明,如果你写的话,你应该很早就熟悉C++,更不用说管理失败或类似传播情况的基础(没有双关语)。
    【解决方案3】:
    int d;
    // can use d before the loop
    for(int a = 0; a < 5; ++a) // can use a or d in the ()
    {
        int b;
        // can use d, a, b in the {}
    }
    int c; 
    // can use d, c after the loop
    

    ab 仅在 for 循环范围内可见。范围包括循环中的内容 (){}

    【讨论】:

    • 您可能还注意到b 不能在循环条件中使用。 (在do{}while() 中更明显)
    • 这是正确的,因为它正确地指出在 () 中声明的项目也是有作用域的。有趣的是,8.0 版(Visual Studio 2005)之前的 MSVC++ 编译器在这部分标准中存在一些问题。
    • 有趣,不知道 () 有它自己的范围,用于从循环到条件(即 b)谢谢。
    【解决方案4】:

    我认为值得一提:

    一些编译器可能有一个选项影响在 for 循环初始化程序中创建的变量的范围。例如,Microsoft Visual Studio 有一个选项/Zc:forScope(强制符合循环范围)。它默认为标准 c++ 行为。但是,这可以更改,以便 for 循环变量在 for 循环范围之外保持活动状态。如果您使用的是 VS,了解此选项的存在可能会很有用,这样您就可以确保将其设置为所需的行为。不确定是否有任何其他编译器具有此选项。

    由于优化设置和“Dead Store”消除,一些编译器可能会消除它认为不必要的代码。例如,如果在循环内更改的变量没有在循环外的任何地方读取,则循环本身可能会被编译器丢弃。

    例如,考虑以下循环:

    int cnt = 0;
    int trys = MAX_INT;
    while (trys-- > 0)
    {
      cnt += trys;
    }
    

    有些编译器可能会丢弃循环的[内容],因为在循环之后没有使用变量 Cnt。

    【讨论】:

      【解决方案5】:

      只是想添加在 for 或 while 循环中声明的变量也在循环内。例如:

      for (int index = 0; index < SOME_MAX; ++index)
      {
          ...
      }
      
      // index is out of scope here.
      

      【讨论】:

        【解决方案6】:
        int a;
        for(int b=0; b<10; ++b) { 
           int c;
        }
        

        范围好像它是:

        int a;
        {
            int b=0;
        begin:
            if (b<= 10) 
            {
                {
                    int c;
                }
                ++b;
                goto begin;
            }
        }
        

        目的是让变量在明确定义的序列点处超出范围。

        【讨论】:

          【解决方案7】:
          for( int i = 0; i < 10; ++i )
          {
            string f = "foo";
            cout << f << "\n";
          }
          // i and f are both "gone" now
          

          在上面的示例代码中,if 都在 {{ 和 }} 范围内,当执行右大括号时,两个变量都超出了范围。

          原因很简单,标准是这样说的;这就是 C++ 语言的工作原理。

          至于动机,考虑到这对你有利:

          for( ...)
          { 
            std::auto_ptr<SomeExpensiveObject> obj(new SomeExpensiveObject);
          }
          

          在上面的代码中,我们使用 RAII 智能指针来“拥有”我们在循环中创建的昂贵对象。 for 循环的作用域语义规定,每次执行循环后,在该迭代期间创建的对象都将被销毁。

          【讨论】:

          • 从技术上讲,fi 处于更内部的范围内。
          【解决方案8】:

          在 C/C++ 中,在 for 或 while 循环(或任何其他带括号的块)中声明的变量的范围是从左括号到右括号。

          while (some_condition == true)
          {
             int myVar = 3;
          }
          cout << myVar << endl; // This will cause a compilation error
          

          【讨论】:

            【解决方案9】:

            查看此代码

            #include < stdio.h >
            
            int i = 10;  
            int main() {  
            
            for(int i=0; i<3; i++) {  
                fprintf(stdout," for i = %d & upper i = %d\n",i,::i);
            
            }  
            
            while (i>3) {  
                int i = 30;  
                fprintf(stdout," while i = %d & upper i = %d\n",i,::i);  
                i++;  
                fprintf(stdout," while i = %d & upper i = %d\n",i,::i);  
            
            }  
            
            fprintf(stdout,"i = %d \n",i);  
            
            }
            

            在上面的代码中,全局变量 i 与控制 for 循环的变量不同。

            它会打印出来

            for i = 0 & upper i = 10
            for i = 1 & upper i = 10
            for i = 2 & upper i = 10
            

            当 while 循环执行时 - i 内部定义的变量 while 具有局部作用域,而 (i > 3) 下的变量跟随全局变量,并不引用局部作用域。

            地盘。

            【讨论】:

              【解决方案10】:

              变量在循环范围内。 IE。您需要在循环内才能访问它。这就像你在函数中声明一个变量一样,只有函数中的东西可以访问它。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2023-03-31
                • 2023-04-02
                • 2022-12-17
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2022-01-12
                相关资源
                最近更新 更多