目录
一、操作符分类
- 算术操作符
- 移位操作符
- 位操作符
- 赋值操作符
- 单目操作符
- 关系操作符
- 逻辑操作符
- 条件操作符
- 逗号表达式
- 下标引用、函数调用和结构成员
二、讲解操作符
1. 算术操作符
+ - * / % 这个也就是我们所熟知的加减乘除和求模(取余)
- 除了 % 操作符之外,其他的几个操作符可以作用于整数和浮点数。% 操作符的两个操作数必须为整数,返回的是整除之后的余数。
- 对于 / 操作符如果两个操作数都为整数,执行整数除法。而只要至少有一个是浮点数就执行的是浮点数除法。
举个例子:
2. 移位操作符
注:移动的是存储在内存中的补码!(因为整数在内存中存储的是二进制的补码)
<< 左移操作符>> 右移操作符注:移位操作符的操作数只能是整数。
前言:整形的二进制表示
2.1 左移操作
移位规则:左边抛弃,右边补0
2.2 右移操作
移位规则:
- 逻辑右移:右边丢弃,左边补0
- 算术右移:右边丢弃,左边补原符号位
采用逻辑右移还是算术右移,取决于编译器,一般情况,绝大多数编译器采用算术右移。这里以算术右移为例讲解。
和左移操作类似:
注意:对于移位运算符,不要移动负数位,这个是标准未定义的!!!!!
int num = 10 ;
num >> -1 ; //error
3. 位操作符
& //按位与
| //按位或
^ //按位异或
注意:他们全是按二进制位来操作的,且操作数必须是整数!
按位与:只有对应的两个二进制位均为1时,结果位才为1 ,否则为0。
按位或:只要对应的二个二进制位有一个为1时,结果位就为1。
按位异或:当两对应的二进制位相异时,结果为1。
4. 赋值操作符
= 复合赋值符:+= -= *= /= %= >>= <<= &= |= ^=
赋值操作符这里大家应该都了解,我在就说明一个内容:
5. 单目操作符
! 逻辑反操作- 负值+ 正值& 取地址sizeof 操作数的类型长度(以字节为单位)~ 对一个数的二进制按位取反-- 前置、后置--++ 前置、后置++* 间接访问操作符(解引用操作符)(类型) 强制类型转换
!:逻辑反操作
&:取地址
* :间接访问操作符(解引用操作符)
sizeof:操作数的类型长度(以字节为单位)
~ :对一个数的二进制按位取反
-- :前置、后置--
++:前置、后置++
(类型) :强制类型转换
6. 关系操作
>>=<<=!= 用于测试“不相等”== 用于测试“相等”
这个可以用数学来理解,意思大致都是一样的。
唯独注意:==不能比较两个字符串的内容,它比较的是两个字符串的首字符的地址。其次,==和=书写时一定要注意,两者的意思天差地别。
7. 逻辑操作符
&& 逻辑与(并且)两个都为真就是真|| 逻辑或(或者)只要有一个为真就是真只关心真假与二进制无关
8. 条件操作符 (三目操作符)
exp1 ? exp2 : exp3
9. 逗号表达式
exp1, exp2 ,exp3,......expn

10. 下标引用、函数调用和结构成员
1. [ ] 下标引用操作符2. ( ) 函数调用操作符3. 访问一个结构的成员
10.1 [ ] 下标引用操作符
int main()
{
int arr[10];
arr[4] = 5;
//[]下标引用操作符
//操作数 arr和4
}
10.2 ( ) 函数调用操作符
void add(int x, int y)
{
}
int main()
{
add2();
//操作数:add2
add(5, 10);//()函数调用操作符
//操作数:add,5,10
}
10.3 访问一个结构的成员
. 结构体.成员名-> 结构体指针->成员名
11. 表达式求值
11.1隐式类型转换
#include<stdio.h>
int main()
{
char a = 5; //截断 因为char是一个字节也就是8个bit位 所以发生截断
char b = 126;
char c = a + b;
//000000000000000000000000 00000101 a的补码
//截断后 a- 00000101
//000000000000000000000000 01111110 b的补码
//截断后 b- 01111110
//整型提升
//00000000000000000000000000000101 -a
//00000000000000000000000001111110 -b
//00000000000000000000000010000011
//10000011 -c
printf("%d\n", c);
// %d 十进制的方式打印有符号整数
//11111111111111111111111110000011 补码
//11111111111111111111111110000010 反码
//10000000000000000000000001111101 原码
return 0;
}

int main()
{
char c = 1;
printf("%u\n", sizeof(c)); // sizeof(c) ,是1个字节,因为不参与运算
printf("%u\n", sizeof(+c));
//c只要参与表达式运算,就会发生整形提升,表达式 +c ,就会发生提升,所以 sizeof(+c) 是4个字节
printf("%u\n", sizeof(-c));
//表达式 -c 也会发生整形提升,所以 sizeof(-c) 是4个字节,但是 sizeof(c) ,就是1个字节
return 0; }
11.2 算术转换
long doubledoublefloatunsigned long intlong intunsigned intint (向上转换)⬆
12. 操作符的属性
- 操作符的优先级
- 操作符的结合性
- 是否控制求值顺序。
例如:a + b * c 肯定是先计算* 再计算 +