为什么一个expression式而不是一个常量,在C for-loop的条件?

在许多编程竞赛中,我看到人们为这种for回旋”编写了这种types

 for(i = 0; i < (1 << 7); i++) 

除非我失去了一些东西,那就是一样的

 for(i = 0; i < 128; i++) 

为什么要使用(1 << 7)版本?
是不是每次都计算不必要的开销?

是的,他们在行为上是等同的。

那么为什么人们使用(1 << 7)版本呢?

我想,他们用它来logging它是2的力量。

每次计算条件必须是开销! 我无法find背后的原因!

不是真的,任何普通的编译器都会用128来代替1 << 7 ,所以两个循环都会有相同的性能。

(C11,6.6p2)“常量expression式可以在翻译过程中而不是在运行时进行评估,因此可以用在常量可能存在的任何地方。

让我们把这些选项中的每一个翻译成简单的英文:

 for(i = 0; i < (1 << 7); i++) // For every possible combination of 7 bits for(i = 0; i < 128; i++) // For every number between 0 and 127 

运行时行为在两种情况下都应该是相同的。

事实上,假设一个体面的编译器,即使汇编代码应该是相同的。

所以第一个选项基本上是用来“发表声明”。

你可以使用第二个选项,并在上面添加注释。

1 << 7是一个常量expression式,编译器将其视为128 ,运行时没有开销。

没有循环体,很难说为什么作者使用它。 可能是一个循环迭代7位相关的东西,但这只是我的猜测。

那么为什么人们使用(1 << 7)版本呢?

它是一种文档forms,它不是一个神奇的数字,而是2^7二至七 ),这对编写代码的人来说是有意义的。 一个现代的优化编译器应该为这两个例子生成完全相同的代码,所以使用这个表单是没有代价的,并且有添加上下文的好处。

使用godbolt我们可以证实这确实是这样的,至less对于几个版本的gccclangicc 。 使用一个带有副作用的简单例子来确保代码不会被完全优化掉:

 #include <stdio.h> void forLoopShift() { for(int i = 0; i < (1 << 7); i++) { printf("%d ", i ) ; } } void forLoopNoShift() { for(int i = 0; i < 128; i++) { printf("%d ", i ) ; } } 

对于代码的相关部分,我们可以看到他们都生成了以下生活 :

 cmpl $128, %ebx 

我们拥有的是C11标准草案中定义的整型常量expression式 。6.6 常量expression式 ,它表示:

整数常量expression式117)应具有整数types,并且只应具有整数常量,枚举常量,字符常量,sizeofexpression式的结果为整数常量的操作数,[…]

和:

常数expression式不得包含赋值,增量,减量,函数调用或逗号运算符,除非它们包含在未评估的子expression式中。

我们可以看到,在翻译过程中可以对一个常量expression式进行评估:

常量expression式可以在翻译过程中而不是在运行时进行评估,因此可以用在常量可能存在的任何地方。

for(i = 0; i <(1 << 7); i ++)

for(i = 0; i <128; i ++)

(i = 0; i <(1 << 7); i ++)在循环中使用

 for(int k = 0; k < 8; k++) { for(int i = 0; i < (1 << k); i++) { //your code } } 

现在它在内环上限即(1 << k)随着2个运行时间的功率而变化。 但是,如果你的algorithm需要这个逻辑,它是适用的。

编译器为这两种情况输出相同的代码。 你可能要根据上下文使用不同的forms。

  1. 您可以使用NUM_STEPSNUM_ELEMENTS_IN_NETWORK_PACKET作为algorithm中的一个常量部分或devise选项。
  2. 或者你可以写128 ,明确它是128 ,一个常数。
  3. 或者如果你参加一个比赛,并且testing中说“跑了2 7次”,那就1 << 7

或者,你可以炫耀,你知道一点操作!

在我看来,编程就像为两个人写信,编译器和需要阅读的人。 你的意思应该清楚。

由于两个操作数都是常量,所以由预处理器评估。

但是如果你打算使用数字而不是位移不应该是0x0100?

Interesting Posts