运算符包括算术运算符、关系运算符、逻辑运算符、赋值运算符、逗号运算符等
一、运算符分类
1. 算术运算符
符号:+ - * / % ++ --(加,减,乘,除,取余,自增,自减)
其中+ - * / %为双目运算符(两个操作数),++ --为单目运算符(一个操作数)
对于整型除法:直接舍去小数,只保留整数,对于浮点除法:保留小数
%取余(求模)只能用于整型(char/short/int/long),不能用于 float/double,其运算结果符号与左操作数保持一致
++、--自增自减可分为前置与后置两种:
前置:++num(--num),先+1(-1)后再使用值;
后置:num++(num--),先使用原值,运算结束后再+1(-1)
注意:自增自减只能作用于变量,不能作用于常量 / 表达式
2.赋值运算符
符号:= += -= *= /= %=(均为双目运算符)
对于赋值运算符,其左值必须是可修改变量,不能是常量、表达式、数组名
复合赋值等价展开:例如num += 10等价于num = num + 10,num %= 3等价于num = num % 3
链式赋值(自右向左结合):例如a = b = c = 5;等价 c=5; b=c; a=b;
3. 关系运算符
符号:< > <= >= == !=(均为双目运算符)
关系运算符的结果为逻辑结果,即1(真),0(假)
需注意:连续比较不能简写,例如6 < j < -2,其等价于等(-6<j) 结果0/1 再与-2比较
4.逻辑运算符
符号:&& || !(逻辑与,逻辑或,逻辑非)
&&逻辑与(双目):全真才为真,一假则假(左右同时为真时结果为真,左右有一个为假结果即为假)
短路:当左边为假时,右边完全不执行
||逻辑或(双目):一真即为真,全假才假(左右有一个为真结果即为真,左右同时为假时结果为假)
短路:当左边为真时,右边完全不执行
!逻辑非(单目):取反,非 0 变 0,0 变 1
5.三目运算符
符号: ? :(唯一三目运算符)
语法:条件表达式?表达式1:表达式2
逻辑:条件为真执行表达式 1,条件为假执行表达式 2
结合性:自右向左,整体是一个表达式,有返回值
6.逗号运算符
符号:,
优先级全运算符最低
规则:从左往右依次执行所有表达式,最终结果为最后一个表达式的值
例如num = 2+3, 4*5, 6-4;等价于(num=5), 20, 2; num=5
用途:for 循环多变量初始化 / 步进
7. sizeof 运算符
功能:用于计算数据 / 变量 / 类型在内存占用字节数,其返回值为unsigned long
例如sizeof(int)或sizeof(num)
64 位系统下所有指针sizeof(指针) = 8字节
数组名单独放入 sizeof:代表整个数组总字节;数组作为函数形参时退化为指针,sizeof 仅为 8
二、运算符优先级
| 层级 | 运算符类型 | 符号 | 结合方向 | |
|---|---|---|---|---|
| 1 | 括号 | () | 左 | |
| 2 | 单目运算符 | ! ~ ++ -- * & sizeof | 右 | |
| 3 | 算术乘除取余 | * / % | 左 | |
| 4 | 算术加减 | + - | 左 | |
| 5 | 移位 | << >> | 左 | |
| 6 | 关系大小比较 | > < >= <= | 左 | |
| 7 | 相等判断 | == != | 左 | |
| 8 | 按位与 | & | 左 | |
| 9 | 按位异或 | ^ | 左 | |
| 10 | 按位或 | ` | ` | 左 |
| 11 | 逻辑与 | && | 左 | |
| 12 | 逻辑或 | ` | ` | 左 |
| 13 | 三目运算符 | ? : | 右 | |
| 14 | 赋值运算符 | = += -= *= /= %= | 右 | |
| 15 | 逗号运算符 | , | 左 |
三、类型转换
C 语言运算时,不同数据类型会自动 / 强制转换,分为隐式自动转换、显式强制转换两大类
1. 隐式类型转换
隐式类型转换系统自动转换,无需手动写代码
运算时编译器自动将低精度 / 小范围类型转为高精度 / 大范围,保证运算精度不丢失
精度优先级(从低→高):
整型:char/short→int→long→unsigned long
浮点:float→double(float 参与运算一定会提升为 double)
无符号 > 同长度有符号(如 unsigned int 高于 int)
整体层级:char/short < int < long < float < double
强制转换规则:
char、short只要参与算术运算、比较运算,无条件先转 int
浮点与整型混合运算:整型转浮点
有符号与无符号同长度运算:有符号转为无符号(极易出现负数变超大正数 bug)
赋值转换(特殊隐式转换) 等号右边类型自动适配左边变量类型,会发生截断 / 补位:
浮点赋值给整型:直接舍弃小数,只保留整数
大数据存入小类型:高位截断,只保留低位字节
小数据存入大类型:正数高位补 0,负数高位补符号位 1
2. 显式强制类型转换
手动转换,格式:(目标类型)表达式
语法:(类型)数据;或(类型)(表达式);
使用复杂表达式建议加括号
特性:
(1)仅临时转换本次运算的值,不会改变原变量本身存储内容
(2)高精度强制转低精度:精度丢失、数值截断、符号错乱
(3)无符号、有符号互相强制转换:直接拷贝内存二进制(补码原样保留)