文章目录
- 1. 操作符的分类
- 2. 原码、反码、补码
- 3. 移位操作符
- 4. 位操作符
- 4.1 位操作符详解
- 4.2 练习
- 4.2.1 不能创建临时变量,实现两个整数的交换
- 4.2.2 求一个整数存储在内存中的二进制1的个数
- 4.2.3 判断一个数是不是2的次方数
- 4.2.4 将二进制第n位置0或置1
- 5. 逗号表达式
- 6. 结构体成员访问操作符
1. 操作符的分类
- 算术操作符:
+ 、- 、* 、/ 、%
- 移位操作符:
<< 、>>
- 位操作符:
& 、^ 、|
- 赋值操作符:
= 、+= 、-= 、*= 、/= 、%= 、<<= 、>>= 、&= 、|= 、^=
- 单目操作符:
!、++ 、-- 、& 、* 、+ 、- 、~ 、sizeof 、(类型)
- 关系操作符:
> 、>= 、< 、<= 、== 、!=
- 逻辑操作符:
&& 、||
- 条件操作符:
? :
- 逗号表达式:
,
- 下标引用:
[ ]
- 函数调用:
( )
2. 原码、反码、补码
- 前面我们讲过二进制、八进制、十进制、十六进制之间的转换,这里不在过多赘述
- 整数的二进制表示方法有三种,分别位原码、反码、补码
- 其中内存中存储的是整数的补码
- 正整数的原码、反码、补码相同
3. 移位操作符
<<
左移操作符>>
右移操作符移位操作符的操作数只能是整数
左移和右移操作符针对的都是二进制的补码进行相应的移位
<<
左移操作符- 左移操作符的规则:左边抛弃,右边补0
#include <stdio.h>
int main()
{
int a = 5;
int b = a << 1;
printf("a=%d\n", a);
printf("b=%d\n", b);
return 0;
}
#include <stdio.h>
int main()
{
int a = -5;
int b = a << 1;
printf("a=%d\n", a);
printf("b=%d\n", b);
return 0;
}
>>
右移操作符- 右移操作符分为两种:逻辑右移、算术右移
- 逻辑右移:左边补0,右边丢弃
- 算术右移:左边补原符号位,右边丢弃
- 逻辑右移和算术右移的使用取决于编译器,不过vs使用的是算术右移
#include <stdio.h>
int main()
{
int a = 5;
int b = a >> 1;
printf("a=%d\n", a);
printf("b=%d\n", b);
return 0;
}
#include <stdio.h>
int main()
{
int a = -5;
int b = a >> 1;
printf("a=%d\n", a);
printf("b=%d\n", b);
return 0;
}
注:移位操作符不能移动负数位,未定义
4. 位操作符
&
按位与|
按位或^
按位异或~
按位取反- 操作数必须是整数,且都是对整数的补码进行相关运算
4.1 位操作符详解
&
按位与- 运算规则:两者都为1才等于1,否则为0
#include <stdio.h>
int main()
{
int a = 5;
int b = 3;
int c = -5;
printf("a & b = %d\n", a & b);
printf("c & b = %d\n", c & b);
return 0;
}
|
按位或- 运算规则:两者都为0才等于0,否则为1
#include <stdio.h>
int main()
{
int a = 5;
int b = 3;
int c = -5;
printf("a | b = %d\n", a | b);
printf("c | b = %d\n", c | b);
return 0;
}
^
按位异或- 运算规则:相同为0,相异为1
#include <stdio.h>
int main()
{
int a = 5;
int b = 3;
int c = -5;
printf("a ^ b = %d\n", a ^ b);
printf("c ^ b = %d\n", c ^ b);
return 0;
}
~
取反- 运算规则:对二进制补码取反
#include <stdio.h>
int main()
{
int a = 5;
printf("%d\n", ~a);
return 0;
}
4.2 练习
4.2.1 不能创建临时变量,实现两个整数的交换
- 方法2
4.2.2 求一个整数存储在内存中的二进制1的个数
- 错误解法
- 正确解法1
- 正确解法2
4.2.3 判断一个数是不是2的次方数
- 2的次方数有一个特点,其二进制有且仅有一位1
//2的次方数有一个特点,其二进制有且仅有一位1
#include <stdio.h>
int main()
{
int n = 0;
printf("请输入>:");
scanf("%d", &n);
if ((n &= (n - 1)) == 0)
{
printf("该数是2的次方数\n");
}
else
printf("该数不是2的次方数\n");
return 0;
}
4.2.4 将二进制第n位置0或置1
//00000000 00000000 00000000 00001101 13
//00000000 00000000 00000000 00011101 第5位置1,其值为29
//00000000 00000000 00000000 00001101 第5位置0
//解题思路
//00000000 00000000 00000000 00001101 13
//00000000 00000000 00000000 00010000 16
//00000000 00000000 00000000 00011101 13 | 16达到第5位置1
//16则可以用1向左逻辑左移<<4位得到
#include <stdio.h>
int main()
{
int n = 13;
n = n | (1 << 4);
printf("%d\n", n);
return 0;
}
//00000000 00000000 00000000 00011101 29
//00000000 00000000 00000000 00001101 第5位置0
//解题思路
//00000000 00000000 00000000 00011101 13
//11111111 11111111 11111111 11101111
//00000000 00000000 00000000 00001101 第5位置0
//00000000 00000000 00000000 00010000 1 << 4
//11111111 11111111 11111111 11101111 ~(1 << 4)
#include <stdio.h>
int main()
{
int n = 29;
n = n & ~(1 << 4);
printf("%d\n", n);
return 0;
}
5. 逗号表达式
- 逗号表达式,就是用逗号隔开的表达式
- 整个表达式的结果就是逗号表达式的最后一个表达式的结果
- 逗号表达式的另一种形式
6. 结构体成员访问操作符
- 结构体关键字- - - >struct
- 结构体变量 . 成员名
- 结构体声明时可同时创建变量
- 结构体嵌套使用