我看到有人使用此方法来增加变量:
r = (r + 1) & 0xf;
这种方法比仅使用更好/更快:
r++;
为什么有人会使用按位,而使用0xf,如果它只是重复?
答案 0 :(得分:14)
那些不一样。第一个增量r然后对它执行模运算,实际上做同样的事情:
r = (r + 1) % 16;
答案 1 :(得分:11)
表达式:
r = (r + 1) & 0xf;
实际与此相当(假设r
保证为非负数):
r = (r + 1) % 16;
因此,无法将上述任何一个陈述与r++
进行比较。哪个“更快”或“更好”并不重要,因为它们首先不会做同样的事情。
答案 2 :(得分:4)
正如其他人所说,您发布的两个代码段不等于。根据该问题的信息更新问题,
r = (r + 1) & 0xf;
比 r = (r + 1) % 16;
更好吗?
虽然可能会出现前一种表示法更适用的情况,但我会说一般 没有 ,它不是。模运算符使发生的事情变得更加清晰,我想大多数编译器都会为您执行此优化。不要不必要地牺牲速度的可读性。 (当然,如果你想确定任何可能的速度差异,只需将两个片段编译成汇编程序,例如使用gcc -S
,并比较输出。)
编辑: nobar下面的评论表明事情通常不像看上去那么简单。与&
不同,%
是算术运算符,它与某些附加规则绑定(例如,确保正确处理否定参数)。上述两个陈述仅等同于非负值或r
。为了确保编译器能够对r
做出这样的假设,最好将其声明为unsigned
。
答案 3 :(得分:3)
这些行不等同。如果在呼叫前r为15,则第一个将返回零。
答案 4 :(得分:2)
r++
来递增。如果不需要后增量功能,大多数编译器会将其优化为++ r,但最好不要依赖它。但是你可能想要在++r
和(r + 1) & 0xf;
之间进行比较,然后我会认为后者可能有一个特定的编译器或硬件的任何小数改进都是微不足道的,相比之下理解上的难度更大并维护代码。
通常,避免在可能不适用于其他架构的优化中过于聪明。
答案 5 :(得分:1)
您给出的两个代码示例中没有等效性 1)是一种快速的方法,将值从0限制为15,并在值超过15时将环绕变为零 2)只增加一个没有上限的值(除了声明r的类型的大小所强加的固有限制,即如果r被声明为unsigned char等,它将包裹> 255)
1)相当于这样做
if (r + 1 > 15 )
{
r = 0;
}
因此,它可能在某些类型的硬件上更加优化,因为它不需要分支等
答案 6 :(得分:1)
比较
r=(r+1) & 0xf;
和
++r;
r %= 0x10;
当r是整数时,任何类型的编译器优化都应该是相同的。
答案 7 :(得分:0)
对于维护代码的程序员来说,也许你应该问自己哪种方法清晰和易于理解 ... C和C ++提供了很多语法来说明在大多数情况下,相同的东西和编译器比程序员更聪明,因此责任在于使代码易于理解。