c++ - 在循环内声明变量,好的做法还是坏的做法?

标签 c++ loops variable-declaration

问题 #1:在循环中声明一个变量是好的做法还是坏的做法?

我已经阅读了关于是否存在性能问题的其他线程(大多数人说没有),并且您应该始终将变量声明为靠近它们将要使用的位置。我想知道的是是否应该避免这种情况,或者它是否确实是首选。

例子:

for(int counter = 0; counter <= 10; counter++)
{
   string someString = "testing";

   cout << someString;
}

问题#2:大多数编译器是否意识到该变量已经被声明并跳过该部分,或者它是否每次都在内存中为它创建一个位置?

最佳答案

这是优秀 实践。

通过在循环内创建变量,您可以确保它们的作用域被限制在循环内。它不能在循环外被引用或调用。

这条路:

  • 如果变量的名称有点“通用”(如“i”),则没有将其与代码后面某个地方的另一个同名变量混合的风险(也可以使用 -Wshadow 警告指令来缓解GCC)
  • 编译器知道变量范围仅限于循环内部,因此如果该变量被错误地引用到其他地方,则会发出正确的错误消息。
  • 最后但并非最不重要的是,编译器可以更有效地执行一些专用优化(最重要的是寄存器分配),因为它知道变量不能在循环外使用。例如,无需存储结果供以后重用。

  • 简而言之,你这样做是对的。

    但是请注意,变量不应在每个循环之间保留其值。在这种情况下,您可能需要每次都对其进行初始化。您还可以创建一个更大的块,包含循环,其唯一目的是声明变量,这些变量必须从一个循环到另一个循环保持其值。这通常包括循环计数器本身。
    {
        int i, retainValue;
        for (i=0; i<N; i++)
        {
           int tmpValue;
           /* tmpValue is uninitialized */
           /* retainValue still has its previous value from previous loop */
    
           /* Do some stuff here */
        }
        /* Here, retainValue is still valid; tmpValue no longer */
    }
    

    对于问题#2:
    当函数被调用时,变量被分配一次。实际上,从分配的角度来看,它(几乎)与在函数开头声明变量相同。唯一的区别是作用域:变量不能在循环之外使用。甚至可能没有分配变量,只是重新使用一些空闲插槽(来自其他作用域已结束的变量)。

    有限的和更精确的范围带来了更准确的优化。但更重要的是,它使您的代码更安全,在阅读代码的其他部分时需要担心的状态(即变量)更少。

    即使在 if(){...} 之外也是如此堵塞。通常,而不是:
        int result;
        (...)
        result = f1();
        if (result) then { (...) }
        (...)
        result = f2();
        if (result) then { (...) }
    

    写这样更安全:
        (...)
        {
            int const result = f1();
            if (result) then { (...) }
        }
        (...)
        {
            int const result = f2();
            if (result) then { (...) }
        }
    

    差异可能看起来很小,尤其是在这么小的例子上。
    但是在更大的代码库上,它会有所帮助:现在传输一些 result 没有风险。值来自 f1()f2()堵塞。每个result严格限制在自己的范围内,使其作用更加准确。从审阅者的角度来看,这要好得多,因为他需要担心和跟踪的远程状态变量更少。

    甚至编译器也会提供更好的帮助:假设将来,在对代码进行一些错误更改后,result未正确初始化 f2() .第二个版本将简单地拒绝工作,在编译时声明一条明确的错误消息(比运行时更好)。第一个版本不会发现任何东西,结果f1()将简单地进行第二次测试,对 f2() 的结果感到困惑.

    补充资料

    开源工具CppCheck (用于 C/C++ 代码的静态分析工具)提供了一些关于变量最佳范围的极好提示。

    回应关于分配的评论:
    上述规则在 C 中是正确的,但可能不适用于某些 C++ 类。

    对于标准类型和结构,变量的大小在编译时是已知的。 C 中没有“构造”这样的东西,所以当函数被调用时,变量的空间将被简单地分配到堆栈中(没有任何初始化)。这就是为什么在循环内声明变量时存在“零”成本的原因。

    但是,对于 C++ 类,我对构造函数知之甚少。我想分配可能不会成为问题,因为编译器应该足够聪明以重用相同的空间,但是初始化可能会在每次循环迭代中进行。

    关于c++ - 在循环内声明变量,好的做法还是坏的做法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7959573/

    相关文章:

    c++ - 是否可以确定(在运行时)功能是否已实现?

    c++ - 折叠表达式扩展包中的最大元素数

    c++ - 用于最小值、最大值、中值、平均值的 OpenMp C++ 算法

    javascript - 我可以使用循环在递增的元素 Id 上多次执行相同的函数调用吗?

    css - 如何让css3动画永远循环

    java - 总是使用Final?

    c++ - 处理文件时出现奇怪的段错误

    c++ - 为什么这个代码片段用 VS2010 编译而不用 GCC 4.5.2?

    c++ - "int (x), 1;"是一个模棱两可的陈述吗?

    javascript - 在不同行上声明和分配变量时返回最后分配的值