大家好,今天给大家带来的是移位操作符、位操作符、二进制详解。
(本章花费3.5小时,若对你有帮助,还请点个免费的赞)
我是黎明_CL,那接下来我们进入主题!
由于我们熟悉10进制,所以我们根据10进制来学习二进制
//正数
int a = 23;
//00000000000000000000000000010111 - 原码
//00000000000000000000000000010111 - 反码
//00000000000000000000000000010111 - 补码
//负数
int b = -22;
//10000000000000000000000000010111 - 原码
//11111111111111111111111111111101000 - 反码(符号位不变,其他位按位取反)
//11111111111111111111111111111100001 - 补码(=反码+1)
整数在内存中存储的是补码,计算时也使用补码
相信聪明的你一定学fei了。
int main()
{
int a = -23;
//10000000000000000000000000010111 - 原码
//11111111111111111111111111101000 - 反码
//11111111111111111111111111101001 - 补码
//算数右移
int b = a >> 1;
//11111111111111111111111111110100 - 补码 右移一位得
//11111111111111111111111111110011 - 反码(=补码-1)
//10000000000000000000000000001100 - 原码 -12
printf("%d\n", a); //-23
printf("%d\n",b); //-12
return 0;
}
int main()
{
int a = 9;
//00000000000000000000000000000101
int b = a << 1;
//【00000000000000000000000000001010】
printf("%d", b); //18
return 0;
}
//原码就是2进制,整形,4个字节,32比特位。正数原码,反码,补码相同。负数反码由原码的符号位不变,其他位按位取反得到,然后反码+1就是补码。整数在内存中存放的是补码,计算的也是补码
//
位操作符—也是操作二进制位
原码
反码
补码
int main()
{
int a = 6;
//00000000000000000000000000000110 - 补码
int b = -5;
//10000000000000000000000000000101 -原
//11111111111111111111111111111010 -反
//11111111111111111111111111111011 -补
int c = a & b;
//00000000000000000000000000000110 - 补码
//11111111111111111111111111111011 -补
//00000000000000000000000000000010 -按位与 &
printf("%d\n", c); // c=2
return 0;
}
//按位或'|'
int main()
{
int a = 6;
//00000000000000000000000000000110 - 补码
int b = -5;
//10000000000000000000000000000101 -原
//11111111111111111111111111111010 -反
//11111111111111111111111111111011 -补
int c = a | b;
//00000000000000000000000000000110 - a补
//11111111111111111111111111111011 -b补
//11111111111111111111111111111111 -补 - (按位或 |)
//11111111111111111111111111111110 -反 -(补码-1)
//10000000000000000000000000000001 -原 -(按位取反)
printf("%d\n", c); //-1
return 0;
}
//a^a—>0
//a^0=a
//假设 a=3 b=5
// a 011
// b 101
// a^b 110
// ①a^b^a110 =5=b
//②a^a^b=b
//0^b=b=5
综上,具有交换率
由此得出异或是支持交换率的
int main()
{
int a = 6;
//00000000000000000000000000000110 - 补
int b = -5;
//10000000000000000000000000000101 -原
//11111111111111111111111111111010 -反
//11111111111111111111111111111011 -补
int c = a ^ b;
//00000000000000000000000000000110 - a补
//11111111111111111111111111111011 - b补
//11111111111111111111111111111101 -补
//11111111111111111111111111111100 -反 -(补码-1)
//10000000000000000000000000000011 -原 -(按位异或)
printf("%d\n", c); //c = -3
return 0;
}
int main()
{
int a = 3;
int b = 7;
//1.创建临时变量
/*int temp = a;
a = b;
b = temp;*/
//2.不创建临时变量
/*a = a + b;
b = a - b;
a = a - b;*/
//通过计算可以得到两数交换的值,可以赋值来思考下实现过程
//但这种交换是有bug的,当值超过表示最大值范围时,会发生数据截断,导致数据错误;
//3.优化终极版本——按位异或实现
a = a ^ b;
b = a ^ b; //此处a等价于a^b,等式等价于b=a^b^b=a
a = a ^ b; //此处b为a,a为a^b,等式等价为a=a^b^a=b
//该交换未进行【进位】,故不会产生值溢出!
//虽然巧妙但缺点在于可读性不高,以后还是使用临时变量swap
printf("a=%d b=%d\n", a, b);
}
步骤如下:
//求一个整数二进制数中1的个数
int main()
{
int a = 0; //整数
int b = 1;
int i = 0; //循环变量
int count = 0;
scanf("%d", &a); //7
for (i = 0; i < 32; i++)
{
int c = a & b;
a = a >> 1;
if ( c== 1)
{
count++;
}
}
printf("%d\n", count); //3
return 0;
}
感谢阅读!创作不易,如果觉得其中有能帮助到您,还请关注我,一起进步。
Live long and Prosper!