目录
1. 操作符的分类
算术操作符: + 、- 、* 、/ 、%
移位操作符: << >>
位操作符: & | ^ `
赋值操作符: = 、+= 、 -= 、 *= 、 /= 、%= 、<<= 、>>= 、&= 、|= 、^=
单目操作符: !、++、--、&、*、+、-、~ 、sizeof、(类型)
关系操作符: > 、>= 、< 、<= 、 == 、 !=
逻辑操作符: && 、||
条件操作符: ? :
逗号表达式: ,
下标引用: [ ]
函数调用: ( )结构成员访问: . 、->
2. 二进制和进制转换
2进制、8进制、10进制、16进制(数值的不同表示形式)
15的2进制:1111
15的8进制:17
15的10进制:15
15的16进制:F
- 10进制中满10进1
- 10进制的数字每一位都是0~9的数字组成
其实二进制也是一样的
- 2进制中满2进1
- 2进制的数字每一位都是0~1的数字组成
1)2进制转10进制
2)2进制转8进制
8进制的数字每一位是0~7的,0~7的数字,各自写成2进制,最多有3个2进制位
如:2进制的01101011,换成8进制:0153,0开头的数字,会被当做8进制
3) 2进制转16进制
16进制的数字每一位是0~9,a ~f 的,0~9 , a ~f的数字,各自写成2进制,最多有4个2进制位
如:2进制的01101011,换成16进制:0x6b,16进制表示的时候前面加0x
3. 原码、反码、补码
整数的2进制表示方法有三种,即原码、反码和补码
有符号整数的三种表示方法均有符号位和数值位两部分,2进制序列中,最高位的1位是被当做符号
位,剩余的都是数值位
符号位都是用0表示“正”,用1表示“负”
正整数的原、反、补码都相同
负整数的三种表示方法各不相同
- 原码:直接将数值按照正负数的形式翻译成二进制得到的就是原码
- 反码:将原码的符号位不变,其他位依次按位取反就可以得到反码
- 补码:反码+1就得到补码
反码得到原码也是可以使用:取反,+1的操作
对于整形来说:数据存放内存中存放的是补码
使用补码可以将符号位和数值域统一处理,同时加法和减法也可以统一处理(CPU只有加法器)此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路
4. 移位操作符
<< 左移操作符
>> 右移操作符
注:移位操作符的操作数只能是整数
1)左移操作符
规则:左边抛弃、右边补0
#include <stdio.h>
int main()
{
int num = 10;
int n = num<<1;
printf("n= %d\n", n);
printf("num= %d\n", num);
return 0;
}
2)右移操作符
规则:首先右移运算分两种
- 逻辑右移:左边用0填充,右边丢弃
- 算术右移:左边用原该值的符号位填充,右边丢弃
#include <stdio.h>
int main()
{
int num = 10;
int n = num>>1;
printf("n= %d\n", n);
printf("num= %d\n", num);
return 0;
}
注意:对于移位运算符,不要移动负数位,这个是标准未定义的
//例如:
int num = 10;
num>>-1;//error
5. 位操作符:&、|、^、~
& //按位与
| //按位或
^ //按位异或
~ //按位取反
//注意:他们的操作数必须是整数
#include <stdio.h>
int main()
{
int num1 = -3;
int num2 = 5; //补码取反(符号位不变)+1 == 原码
//原码取反(符号位不变)+1 == 补码
printf("%d\n", num1 & num2);
//10000000000000000000000000000011 ->-3 原码
//11111111111111111111111111111101 ->-3 补码
& 00000000000000000000000000000101 (位运算)
------------------------------------------------
//00000000000000000000000000000101 -> 5
printf("%d\n", num1 | num2);
//10000000000000000000000000000011 ->-3 原码
//11111111111111111111111111111101 ->-3 补码
| 00000000000000000000000000000101 (位运算)
------------------------------------------------
//11111111111111111111111111111101 ->-3 补码
//10000000000000000000000000000011 ->-3 原码
printf("%d\n", num1 ^ num2);
//10000000000000000000000000000011 ->-3 原码
//11111111111111111111111111111101 ->-3 补码
^ 00000000000000000000000000000101 (位运算)
------------------------------------------------
//11111111111111111111111111111000 ->-8 补码
//10000000000000000000000000001000 ->-8 原码
printf("%d\n", ~0);
//~00000000000000000000000000000000
// 11111111111111111111111111111111 ->补码
// 10000000000000000000000000000001 ->原码 -1
return 0;
}
运行结果:
举例:
1)数值交换
不能创建临时变量(第三个变量),实现两个数的交换
#include <stdio.h>
int main()
{
int a = 10; //a^a==0
int b = 20; //a^0==a
a = a^b;
b = a^b; b= a^b^b -> a^0 -> a
a = a^b; a= a^b^a -> b^0 -> b
printf("a = %d b = %d\n", a, b);
return 0;
}
2)求整数存储在内存中的二进制中1的个数
//方法1
#include <stdio.h>
int main()
{
unsigned int num = 10;//注意 unsigned int 否则num 为负数(-1)结果错误
int count= 0;//计数
while(num)
{
if(num%2 == 1)
count++;
num = num/2;
}
printf("二进制中1的个数 = %d\n", count);
return 0;
}
//方法2:
#include <stdio.h>
int main()
{
int num = -1;
int i = 0;
int count = 0;//计数
for(i=0; i<32; i++)
{
if( num & (1 << i) )
count++;
}
printf("二进制中1的个数 = %d\n",count);
return 0;
}
//方法3:
#include <stdio.h>
int main()
{
int num = -1;
int i = 0;
int count = 0;//计数
while(num)
{
count++;
num = num&(num-1);
}
printf("二进制中1的个数 = %d\n",count);
return 0;
//00000000000000000000000000000011 ->3 原码
& 00000000000000000000000000000010 ->2 原码 3 &(3-1)count++
----------------------------------------------------------------
//00000000000000000000000000000010 ->2 原码
//00000000000000000000000000000001 ->1 原码 2 &(2-1)count++
----------------------------------------------------------------
//00000000000000000000000000000000 ->0 原码 while循环结束 count = 2;
3)二进制位置0或者置1
#include <stdio.h>
int main()
{
int a = 13;
a = a | (1<<4);//置1
//00000000000000000000000000001101
| 00000000000000000000000000010000 (位运算)
-------------------------------------------
//00000000000000000000000000011101
printf("a = %d\n", a);
a = a & ~(1<<4);//置0
//00000000000000000000000000001101
& 11111111111111111111111111101111 (位运算)== ~00000000000000000000000000010000
-------------------------------------------
//00000000000000000000000000001101
printf("a = %d\n", a);
return 0;
}
谢谢观看