限制变量范围的利弊

时间:2014-12-10 06:44:59

标签: c++ c++11

从“C ++编程语言4版”一书中,作者喜欢限制变量的范围。它位于“3.2.1.3初始化容器”一章中

代码是:

Vector read(istream& is)
{
    Vector v;
    for (double d; is>>d;) // read floating-point values into d
    v.push_back(d); // add d to v
    return v;
}

他说

  

我使用了for-statement而不是更传统的语句   while语句将d的范围限制在循环中。

这样做有什么好处?

3 个答案:

答案 0 :(得分:6)

限制范围意味着:

  • RAII类型(管理资源,如文件或网络I / O句柄,内存,线程锁等,并在其析构函数中释放这些资源)使析构函数的清理代码运行得更早,而不是更晚,优化持续时间资源利用对自己的执行和其他程序的潜在利益具有潜在的利益

  • 以后的代码可以为同一个目的重用相同的标识符...如果它们在不同的循环中服务于相同的逻辑目的,那么为什么要继续梦想变量名,但是类型不同?

    < / LI>
  • 在先前无关的使用之后,没有尝试重复使用变量忘记重置其值的风险

  • 程序员在使用范围之后分析代码时,不需要记住代码;总而言之,自信地理解代码所需的交叉引用和搜索要少得多

  • 您可以在各种使用环境中使用auto以避免此类错误......

    float x;
    for (x = my_floats.first(); x < 10; x = my_floats.next())
        ...

    for (x = my_doubles.first(); x < 10; x = my_doubles.next())
        ... oops... getting float precision when double available...
  • 如果随着代码的发展,您希望更改变量名称和/或类型以反映其使用,您可以更加轻松地以本地化方式执行此操作,而不会通过其他代码误导名称,或者类型变得不合适(也许与上面的float / double示例一样,无声地降级结果;即使没有具有“重构”支持的花哨IDE,编译器错误也可以帮助您在本地范围内准确地进行更改,而无需进行(更容易出错)全局搜索并替换...

答案 1 :(得分:3)

在@TonyD的回答之上:

  • 理想情况下,您应该将变量声明为尽可能接近您正在使用它们的位置。

    这使得代码在没有到达使用该值的执行分支时更快。

    示例:

    void f()
    {
        std::string s{ "will be interesting later" ); // some local variable that
                                                      // could have been declared
                                                      // lower in the code
        void g(); // may throw
        use(s);
    }
    

    根据s的大小,分配它可能是一项昂贵的操作。如果g抛出,则不需要s,并且为其分配的资源将被浪费。在调用g之前分配s也意味着g将以更少的可用资源运行(考虑到这些天的计算机功能,在大多数情况下这实际上并不重要)。

  • 将声明靠近您使用它们的位置意味着滚动查看类型定义是不必要的。你必须向上滚动才能看到的声明“看不见”(因此,不在乎:) :)。

  • 编辑/手动重构。考虑想要将对use的调用提取到另一个函数:如果上面的代码之间没有调用g,则可以复制&amp;糊。这样,您可以粘贴整个块,然后移除对g的调用,或复制两次(用于定义s和调用use)。

答案 2 :(得分:1)

在for循环范围内声明和初始化变量i背后的最简单原因是保持代码的简单调试和理解,并防止整个程序执行时计数器变量不必要地使用内存。

在以下代码中,变量i超出for循环的范围,也会影响循环外的代码。但是它只是用作循环的计数器变量。这种样式只应该被采用,并且只有在你想要保留和使用循环计数器的值超出循环范围时才会被采用。

int main()
{
    int bigNumber = 10;
    int i;
    for(i = 0; i != bigNumber; ++i){
       cout<<i;
       if(i==2)
       break;
    }
    cout<<"loop terminated at"<<i;
    return 0;
}

就第二种样式而言,它确保变量i的作用和值仅限于循环范围。在下面给出的代码中,您将无法使用超出循环范围的计数器变量,从而导致错误。这有助于防止计数器变量使用不必要的内存。

int main()
{
    int bigNumber = 10;
    for(int i = 0; i != bigNumber; ++i){
        cout<<i; 
    }
   cout<<i;
   return 0;
}