1.求下面代码输出的结果
考察点:全局变量 sizeof结果的类型
#include <stdio.h>
int i;
int main()
{
i--;
if (i > sizeof(i))
{
printf(">\n");
}
else
{
printf("<\n");
}
return 0;
}
输出结果: >
全局变量,没有给初始值时,编译其会默认将其初始化为0。
i的初始值为0,i--的结果-1,i为整形,sizeof(i)求i类型大小是4,按照此分析来看,结果应该为<,但是sizeof的返回值类型实际为无符号整形,因此编译器会自动将左侧i自动转换为无符号整形的数据,-1对应的无符号整形是一个非常大的数字,超过4或者8,故实际应该选择
2.统计二进制中1的个数
目标:写一个函数返回参数二进制中 1 的个数。
比如: 15 0000 1111 4 个 1
方法一:
思路:循环进行以下操作,直到n被缩减为0:
1. 用该数据模2,检测其是否能够被2整除
2. 可以:则该数据对应二进制比特位的最低位一定是0,否则是1,如果是1给计数加1
3. 如果n不等于0时,继续+1
int count_one_bit(int n)
{
int count = 0;
while(n)
{
if(n%2==1)
count++;
n = n/2;
}
return count;
}
方法二:
对该二进制数的32位,一位一位检查
int count_one_bit(int n)
{
int count = 0;
int i=0;
for(i=0;i<32;i++)
{
if((n>>i)&1)==1)
count++;
}
return count;
}
方法三:
思路:相邻两个数,利用位运算‘与’,计算11的个数
例子:9999 : 10 0111 0000 1111
第一次循环 n=9999 n=n&(n-1)=9999&9998=9998 第二次循环 n=9998 n=n&(n-1)=9998&9997=9998 第三次循环 n=9996 n=n&(n-1)=9996&9995=9998 第四次循环 n=9992 n=n&(n-1)=9992&9991=9998 第五次循环 n=9984 n=n&(n-1)=9984&9983=9998 第六次循环 n=9728 n=n&(n-1)=9728&9727=9998 第七次循环 n=9216 n=n&(n-1)=9216&9215=9998 第八次循环 n=8192 n=n&(n-1)=8192&9181=0
int count_one_bit(int n)
{
int count = 0;
while(n)
{
n = n&(n-1);
count++;
}
return count;
}
例如:n&(n-1)
//查找1101 - n
1100 - n-1
1100 - n
1001 - n-1
1000 - n
3.下面代码的结果是:( )
#include <stdio.h> int main() { int i = 1; int ret = (++i)+(++i)+(++i); printf("ret = %d\n", ret); return 0; }
无法确定结果。
表达式(++i)+(++i)+(++i),只有操作符的优先级和结合性,没法确定唯一计算路径
所以这个表达式可能因为计算顺序的差异导致结果是不一致的,所以表达式是错误的表达式。可以在VS和Linux gcc测试,结果可能有差异。