C++ `for(…)`语句中的计算

C++ `for(…)`语句中的计算,c++,C++,很多时候我看到的代码如下: int s = a / x; for (int i = 0; i < s; i++) // do something 然后假设编译器优化了a/x,即用常量替换它?int s=a/x最重要的部分是变量名。它给出了你的语法语义,并让你记住12个月后你为什么要把一件事和另一件事分开。您无法在for语句中命名表达式,因此您失去了自我记录的特性 const auto monthlyAmount = (int)yearlyAmount / numberOfMont

很多时候我看到的代码如下:

int s = a / x;
for (int i = 0; i < s; i++)
    // do something

然后假设编译器优化了
a/x
,即用常量替换它?

int s=a/x最重要的部分是变量名。它给出了你的语法语义,并让你记住12个月后你为什么要把一件事和另一件事分开。您无法在
for
语句中命名表达式,因此您失去了自我记录的特性

const auto monthlyAmount = (int)yearlyAmount / numberOfMonths;
for (auto i = 0; i < monthlyAmount; ++i)
    // do something
const auto monthlyAmount=(int)yearlyAmount/numberofmonth;
用于(自动i=0;i

这样,提取变量不是为了编译器优化,而是为了人的可维护性优化。

优化的问题可能源于这样一个事实,即在每次迭代之前都会对条件进行评估。如果这是一个潜在的昂贵操作,并且您不需要反复执行,那么您可以将其从循环中提取出来:

const std::size_t size = s.size(); // just an example
for (std::size_t i = 0; i < size; ++i)
{
}
const std::size\u t size=s.size();//只是一个例子
对于(标准::大小\u t i=0;i

对于便宜的操作,这可能是过早的优化,编译器可能会生成相同的代码。唯一可以确定的方法是检查生成的汇编代码。

如果编译器可以确定在for循环中的表达式中使用的变量在迭代之间不会改变,那么它可以优化循环开始时执行的计算,而不是每次迭代。

但是,考虑使用的变量是全局变量,或者引用到函数外部的变量,在for循环中调用函数。该函数可以更改这些变量。如果编译器当时能够看到足够多的代码,它就可以发现是否是这种情况,从而决定是否进行优化。但是,编译器只愿意查看到目前为止(否则编译会花费更长的时间),因此一般来说,您不能假设优化已经执行。

此类问题的问题是它们无法概括。编译器将执行哪些优化以及不执行哪些优化只能通过个案分析来确定。 如果下列情况之一成立,我当然希望编译器能够这样做:

1) A和B都是局部变量,它们的地址永远不会被获取

2) 循环中的代码是完全内联的


实际上,最后一个需求并不像看上去那么难,因为如果主体中的函数无法内联,它们的运行时间很可能会缩短重新计算绑定的时间

或检查生成的汇编代码以确保安全。如果存在可能的别名,或者如果
a
x
是全局的,并且您调用可以修改
a
x
的函数,优化是不可能的。
a
x
是常数吗?确保的唯一方法是将其存储在局部变量中。在某些情况下,它可以被优化。@remyabel:不是每个人都会说汇编。这是一个很好的建议,但它不能回答问题。这一点很好!答案是“不,你不能这样做,因为你的同事会用办公用品殴打你。”更严重的是,任何健全的编码标准文件都会鼓励这种情况下使用命名良好的变量。自愿且反复违反公司文件是被解雇的好方法。您应该强调,您已将分配更改为
const
变量。OP在示例中没有使用
const
。我同意这一点,并且我认为指出这一点很好。然而,在某些情况下,我只是想限制代码行数,而且我还试图理解如何编写优化的代码,所以这就是我提出这个问题的原因。我给这个答案打了一分,因为它提供了有用的信息,但是我没有选择这个答案,因为它没有回答实际问题。
const std::size_t size = s.size(); // just an example
for (std::size_t i = 0; i < size; ++i)
{
}