一、
题目:
求a,b,c的值
nt main()
{
int a, b, c;
a = 5;
c = ++a;//c=6,a=6
b = ++c, c++, ++a, a++;//c=8,a=8,b=7
b += a++ + c;//a=9,b=23,注意先使用后++
printf("%a=%d b=%d c=%d:\n", a, b, c);
return 0;
}
注意:
1、a++,++a,此时a的值自增了1
2、逗号操作符——,,,
三个表达式都需要计算,而最后的值就是最后一个表达式。
3、 +的优先级比+=大
4、b += a++ + c;
b加上的是a原来的值,因为先使用后++
二、
题目:
计算一个参数的二进制位补码的1的个数
TIP:正数的原码补码反码相同,负数存储在内存使用的是补码。
思路一:
这类题型跟计算十进制位中1的个数一样,不同区别就在于一个十进制位,一个二进制位,因此一个/10%10,一个/2%2。
int Numberof1(int n)
{
int cnt = 0;
while (n)
{
if (n % 2 == 1)
{
cnt++;
}
n /= 2;
}
return cnt;
}
int main()
{
int n = 0;
scanf("%d", &n);
int ret = Numberof1(n);
printf("%d\n", ret);
return 0;
}
这类方法只适用于正数,但也可以在函数用无符号整数进行接收,将-1变成无符号整数,将-1补码的无符号数变为有效位,无符号数的原码补码反码相同,就变成32个1。
思路2:
按位与操作符和移位操作符的结合
按位与&1便于求一个数的二进制位中的最后一个数是1还是0.
注意这个结论可以便于记忆&操作符的作用,一举两得!
一个数&1如果结果是1,说明这个数的二进制位的最低位就是1,&1的结果是0,则就是0。就是原来的数字!
移位操作符,>>向右移动一个二进制位
int Numberof1(int n)
{
int cnt = 0;
for (int i=0;i<=32;i++)
{
if (n & 1 == 1)
{
cnt++;
}
n >>= 1;
}
return cnt;
}
int main()
{
int n = 0;
scanf("%d", &n);
int ret = Numberof1(n);
printf("%d\n", ret);
return 0;
}
思路三(推荐)
直接n=n&(n-1),并计算执行这一语句的次数,直到n=0.
思路一和思路二算法复杂度都是O(n),而本题的算法复杂度明显要比O(n)少!
int main()
{
int n = 0;
scanf("%d", &n);
int cnt = 0;
while (n)
{
n = n & (n - 1);
cnt ++ ;
}
printf("%d\n", cnt);
return 0;
}
三、
题目:两个整数二进制位中不同位的个数
思路一:
比较笨的算法,上一道题我们已经可以求出二进制中的每一位,所以这一道题可以沿用上一道的算法,将这两个数的二进制位的每一位进行比较。
int solve(int a, int b)
{
int cnt = 0;
for (int i=0;i<32;i++)
{
if (((a>>i) & 1) != ((b>>i) & 1))
{
cnt++;
}
}
return cnt;
}
int main()
{
int a, b = 0;
scanf("%d %d", &a, &b);
int ret = solve(a, b);
printf("%d\n", ret);
return 0;
}
思路2:
介绍另外一个操作符——^ 按位异或
相异为1,相同为0.(注意是针对每一个二进制位,比如整型类型,32位都需要进行按位异或)
可以将两个数直接异或,然后得到的二进制位存储起来,接着再将上面一道题的思路三沿用即可
比思路一更加简便!
int main()标签:cnt,二进制位,转换,算术,++,int,return,main From: https://blog.51cto.com/u_15740457/6129812
{
int a, b = 0;
scanf("%d %d", &a, &b);
int c = a ^ b;
int cnt = 0;
while (c)
{
c = c & (c - 1);
cnt++;
}
printf("%d\n", cnt);
return 0;
}