我在接受采访时得到了以下问题:"编写一个C函数,将一个数字向下舍入到下一个2的幂".
我写了以下答案:
#include <stdio.h>
int next_pwr_of_2(int num)
{
int tmp;
do
{
num++;
tmp=num-1;
}
while (tmp & num != 0);
return num;
}
void main()
{
int num=9;
int next_pwr;
next_pwr=next_pwr_of_2(num);
printf(" %d \n",next_pwr);
}
Run Code Online (Sandbox Code Playgroud)
问题是:为什么程序do-while在达到11和10值时会退出循环?
axi*_*iom 28
优先考虑我的朋友,优先.
while ((tmp & num) != 0);
会解决它.(注意表达式周围的括号tmp & num)
!=优先级高于&,num != 0之前进行评估tmp & num.
如果跳过括号,则计算的表达式为: tmp & (num != 0)
圆第一次,tmp = 9 (1001)而且num != 0是1 (0001)这样&的计算结果为1(真),并继续循环.
现在在第二次迭代结束时,我们有,tmp = 10 (1010).num != 0再次为0001,因此1010 & 0001评估为0,因此循环中断.
这是表格供参考.
优先顺序是相当不寻常的,因为注意到这里.一直发生:).
当然,你不必记住任何优先顺序,这只是为了帮助编译器在决定什么是第一次做,如果程序员不说清楚.您可以正确地将表达式括起来并避免出现这种情况.
das*_*ght 20
循环退出是因为您没有在您的条件周围放置括号.这应该教你不要把不必要的东西!= 0放在你的C/C++条件下.
不过,您可以简化代码.
首先,观察它temp等于先前的值num,因此您可以将循环更改为
int tmp;
do {
tmp = mum++;
} while (tmp & num); // Don't put unnecessary "!= 0"
Run Code Online (Sandbox Code Playgroud)
其次,面试官可能想看看你是否熟悉这个小技巧:
v--;
v |= v >> 1;
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;
v++;
Run Code Online (Sandbox Code Playgroud)
与您的代码可能需要多达1,000,000,000次操作完成不同,上述操作总是在12次操作(减量,增量,5次和5次OR)后完成.