int main()
{
int a = 20;
int b = 12;
printf("a + b = %d\n", a + b);
printf("a - b = %d\n", a - b);
printf("a÷b = %d\n", a / b); // 这里20除12等于1,他不会显示后面的小数,除非计算式两边至少有一个浮点数
printf("a×b = %d\n", a * b);
printf("a % b = %d\n", a % b); // 这里20模12余数是8,结果便是8
return 0;
}
#include <stdio.h>
int main()
{
int a = 10;
int b = -5;
printf("%d\n", a >> 1); // 5
printf("%d\n", b >> 1); // -3
// b计算过程
// 原码:10000000000000000000000000000101
// 反码:11111111111111111111111111111010
// 补码:11111111111111111111111111111011
// 右移:11111111111111111111111111111101
// 减一:11111111111111111111111111111100
// 取反:10000000000000000000000000000011
// 右移1后的数为 10000000000000000000000000000011 - (-3)
return 0;
}
无论是左移还是右移,我们都不能移动负数为,如: a >> -1.
3.位操作符
同样的,位操作符也是对补码进行计算
3.1 &
按位与是 : 如果两个二进制补码相同位数上有一个为零则为0,都为1则为1.
#include <stdio.h>
int main()
{
int a = -5;
// 原:10000000000000000000000000000101
// 反:11111111111111111111111111111010
// 补:11111111111111111111111111111011
int b = 3;
// 原:00000000000000000000000000000011
// 补:00000000000000000000000000000011
// a & b
// 补:11111111111111111111111111111011
// 补:00000000000000000000000000000011
// 有一个0则为0,都为1则1
// 得:00000000000000000000000000000011
// 为整数:3
printf("%d", a & b);
return 0;
}
3.2 |
按位或是 : 如果两个二进制补码相同位数上只要有一个为1则为1,全0则0.
#include <stdio.h>
int main()
{
int a = 10;
// 补:00000000000000000000000000001010
int b = -2;
// 原:10000000000000000000000000000010
// 反:11111111111111111111111111111101
// 补:11111111111111111111111111111110
// a | b
// 00000000000000000000000000001010
// 11111111111111111111111111111110
// 11111111111111111111111111111110 结果
// 减一:11111111111111111111111111111101
// 取反:10000000000000000000000000000010 (-2)
printf("%d", a | b); // -2
return 0;
}
3.3 ^
按位异或是:相同为0,相异为1.
#include <stdio.h>
int main()
{
int a = 3;
// 补:00000000000000000000000000000011
int b = 5;
// 补:00000000000000000000000000000101
// a ^ b
// 00000000000000000000000000000011
// 00000000000000000000000000000101
// 00000000000000000000000000000110 - 6
printf("%d\n", a ^ b); // 6
printf("%d\n", a ^ 0); // a
printf("%d\n", b ^ 0); // b
printf("%d\n", a ^ a); // 0
return 0;
}
值得注意的是:
a ^ 0 = a;
b ^ 0 = b;
a ^ a = 0;
那么可以得到:
a ^ a ^ b = b;
b ^ b ^ a = a;
有一道经典题目:不创建临时变量交换两个变量的值。我们便可以用上述推理来实现
#include <stdio.h>
int main()
{
int a = 3;
int b = 5;
printf("交换前:%d %d\n", a, b);
a = a ^ b;
b = a ^ b;
a = a ^ b;
printf("交换后:%d %d\n", a, b);
return 0;
}
3.4 ~
按位取反是补码二进制位如果是1则变为0,如果是0则变为1。
#include <stdio.h>
int main()
{
int a = 3;
// 补:00000000000000000000000000000011
// 反:11111111111111111111111111111100 补码变负
// -1:11111111111111111111111111111011
// 原:10000000000000000000000000000100 -4
printf("%d", ~a);
return 0;
}
#include <stdio.h>
int main()
{
int a = 0;
int b = 1;
int c = 2;
int d = 3;
int i = a++ && ++b && c++; // a++表达式结果为a的值,此时a=0,由&&的性质有一个为假就为假,则后面都不计算了
//但是a++还是要进行计算的,也就是a要自增1
printf("%d %d %d %d\n", a, b, c, d);
// 结果为 1 1 2 3
return 0;
}
||
逻辑或:如 a || b,当a,b中只要有一个为真,表达式为真,都为假表达式才为假
#include <stdio.h>
int main()
{
int a = 1;
int b = 2;
int c = 3;
int d = 4;
int i = a++ || b++ || ++d || c--; // a++表达式结果为a,此时a=1为真,由||性质,整个表达式结果为真,则后面的不计算了
// a++还是要计算的,也就是a要自增1
printf("%d %d %d %d\n", a, b, c, d);
// 结果为 2 2 3 4
return 0;
}
int main()
{
int a = 20;
int b = 12;
printf("a + b = %d\n", a + b);
printf("a - b = %d\n", a - b);
printf("a÷b = %d\n", a / b); // 这里20除12等于1,他不会显示后面的小数,除非计算式两边至少有一个浮点数
printf("a×b = %d\n", a * b);
printf("a % b = %d\n", a % b); // 这里20模12余数是8,结果便是8
return 0;
}
#include <stdio.h>
int main()
{
int a = 10;
int b = -5;
printf("%d\n", a >> 1); // 5
printf("%d\n", b >> 1); // -3
// b计算过程
// 原码:10000000000000000000000000000101
// 反码:11111111111111111111111111111010
// 补码:11111111111111111111111111111011
// 右移:11111111111111111111111111111101
// 减一:11111111111111111111111111111100
// 取反:10000000000000000000000000000011
// 右移1后的数为 10000000000000000000000000000011 - (-3)
return 0;
}
无论是左移还是右移,我们都不能移动负数为,如: a >> -1.
3.位操作符
同样的,位操作符也是对补码进行计算
3.1 &
按位与是 : 如果两个二进制补码相同位数上有一个为零则为0,都为1则为1.
#include <stdio.h>
int main()
{
int a = -5;
// 原:10000000000000000000000000000101
// 反:11111111111111111111111111111010
// 补:11111111111111111111111111111011
int b = 3;
// 原:00000000000000000000000000000011
// 补:00000000000000000000000000000011
// a & b
// 补:11111111111111111111111111111011
// 补:00000000000000000000000000000011
// 有一个0则为0,都为1则1
// 得:00000000000000000000000000000011
// 为整数:3
printf("%d", a & b);
return 0;
}
3.2 |
按位或是 : 如果两个二进制补码相同位数上只要有一个为1则为1,全0则0.
#include <stdio.h>
int main()
{
int a = 10;
// 补:00000000000000000000000000001010
int b = -2;
// 原:10000000000000000000000000000010
// 反:11111111111111111111111111111101
// 补:11111111111111111111111111111110
// a | b
// 00000000000000000000000000001010
// 11111111111111111111111111111110
// 11111111111111111111111111111110 结果
// 减一:11111111111111111111111111111101
// 取反:10000000000000000000000000000010 (-2)
printf("%d", a | b); // -2
return 0;
}
3.3 ^
按位异或是:相同为0,相异为1.
#include <stdio.h>
int main()
{
int a = 3;
// 补:00000000000000000000000000000011
int b = 5;
// 补:00000000000000000000000000000101
// a ^ b
// 00000000000000000000000000000011
// 00000000000000000000000000000101
// 00000000000000000000000000000110 - 6
printf("%d\n", a ^ b); // 6
printf("%d\n", a ^ 0); // a
printf("%d\n", b ^ 0); // b
printf("%d\n", a ^ a); // 0
return 0;
}
值得注意的是:
a ^ 0 = a;
b ^ 0 = b;
a ^ a = 0;
那么可以得到:
a ^ a ^ b = b;
b ^ b ^ a = a;
有一道经典题目:不创建临时变量交换两个变量的值。我们便可以用上述推理来实现
#include <stdio.h>
int main()
{
int a = 3;
int b = 5;
printf("交换前:%d %d\n", a, b);
a = a ^ b;
b = a ^ b;
a = a ^ b;
printf("交换后:%d %d\n", a, b);
return 0;
}
3.4 ~
按位取反是补码二进制位如果是1则变为0,如果是0则变为1。
#include <stdio.h>
int main()
{
int a = 3;
// 补:00000000000000000000000000000011
// 反:11111111111111111111111111111100 补码变负
// -1:11111111111111111111111111111011
// 原:10000000000000000000000000000100 -4
printf("%d", ~a);
return 0;
}
#include <stdio.h>
int main()
{
int a = 0;
int b = 1;
int c = 2;
int d = 3;
int i = a++ && ++b && c++; // a++表达式结果为a的值,此时a=0,由&&的性质有一个为假就为假,则后面都不计算了
//但是a++还是要进行计算的,也就是a要自增1
printf("%d %d %d %d\n", a, b, c, d);
// 结果为 1 1 2 3
return 0;
}
||
逻辑或:如 a || b,当a,b中只要有一个为真,表达式为真,都为假表达式才为假
#include <stdio.h>
int main()
{
int a = 1;
int b = 2;
int c = 3;
int d = 4;
int i = a++ || b++ || ++d || c--; // a++表达式结果为a,此时a=1为真,由||性质,整个表达式结果为真,则后面的不计算了
// a++还是要计算的,也就是a要自增1
printf("%d %d %d %d\n", a, b, c, d);
// 结果为 2 2 3 4
return 0;
}