运算符:
运算符 |
结合性 |
优先级 |
() [] -> . |
左 |
1 |
! ~ ++ -- +(单目,正号) -(单目,负号) *(解引用运算符) &(取地址运算符) (类型) sizeof |
右 |
2 |
*(乘法) / % |
左 |
3 |
+(双目,加法) -(双目,减法) |
左 |
4 |
<< >> |
左 |
5 |
< <= > >= |
左 |
6 |
==(逻辑等于) != |
左 |
7 |
&(按位与) |
左 |
8 |
^ |
左 |
9 |
| |
左 |
10 |
&& |
左 |
11 |
|| |
左 |
12 |
?: |
右 |
13 |
=(赋值等于) += -= *= /= %= &= ^= |= <<= >>= |
右 |
14 |
, |
左 |
15 |
左右结合的定义:
多个相同运算符,或同一优先级运算符存在时,从左至右或从右至左的运算顺序
算术运算符:
单目+和单目-,以及双目的+,-,*,/和%
算术运算的结果即为运算式的结果
关系运算符:
< <= > >= == !=
关系运算的结果为int,为0或1(0假1真)
逻辑运算符:
操作对象为0或非0的一个表达式
!(单目逻辑非,操作数为非0,则输出1,反之为0)
&&(双目逻辑与,有0则输出0,若第一个操作数为0,则不再计算第二个操作数)
||(双目逻辑与,有非0则输出1,若第一个操作数为非0,则不再计算第二个操作数)
逻辑运算的结果为int,为0或1(0假1真)
自增与自减运算符:
结果类型与操作数类型一致
++和--
注意:++x和x++表达不同的意思
++x是先让x自增,再返回x自增之后的值;而x++是先让x返回初始值,再让x自增
序列点:规范自增在某一进程前完成的位置
包括&&、||、?:、和逗号运算符的第一个操作数结尾处,以及完整表达式的结束
赋值运算符:
简单赋值:操作数1=操作数2
数1必须是一个可改变内容的左值表达式
过程是首先计算操作数2的值,然后将该值赋给操作数1对应的储存单元,执行赋值之前操作数被自动转换为操作数1的类型
简单赋值运算的值和类型与操作数1相同
复合赋值:操作数1 op =操作数2 或 操作数1 =操作数1 op操作数2 (但不一定等价,左值计算次数1次和2次同会影响效率,部分情况下影响结果)
op代表加、减、乘、除、求余,以及<<、>>、&、^和|
条件运算符:
操作数1?操作数2:操作数3
如果操作数1的值非0,则计算操作数2,并以其值作为结果;如果操作数1的值为0,则计算操作数3,并以其值作为结果
注意:不会计算未被选中的分支
表达式类型由操作数2和操作数3确定
逗号运算符:
操作数1,操作数2,操作数3,……,操作数n
表达式从左到右依次计算各个操作数,表达式的值和类型由操作数n决定
要用到逗号运算符时,需要用括号把含有逗号运算符的逗号表达式括起来
sizeof运算符:
sizeof(类型名):给出指定数据类型占用的存储字节数
sizeof表达式:给出表达式结果的类型占用的存储字节数,表达式可有或无括号,若无,sizeof与表达式之间要有空格
Sizeof在编译时确定类型,不在运行时对表达式求值(例如,在sizeof里的复合赋值不影响原左值)
位逻辑运算符:
~a 按位取反:对操作数上的每一个位取相反值;
a&b 按位与:对两个操作数上的每一位进行与运算,两个同时为1则为1,其他都是0;
a|b 按位或:对两个操作数上的每一位进行或运算,两个同时为0则为0,其他都是1;
a^b 按位和:对两个操作数上的每一位进行不进位的加法运算,两个相同则为0,不同则为1;
移位运算:
a<<b 左移:将左操作数的每一位向左移动右操作数指定的位数,高位被移出,低空位填0;
a>>b 右移:将左操作数的每一位向右移动右操作数指定的位数,低位被移出,高空位填0或1(由操作数类型及系统决定);
类型转换
1、整数提升:表达式中char和short(整数类型)会自动转换成int(有符号)或unsigned(无符号)类型,若所有值都能用int表示,则用int,否则转换为unsigned(很少,可能出现在16位系统中)两个数不一定转成一样的类型;
2、算术转换:对于整数提升后操作数类型不同的两个数,会发生算术转换,原则是值域较窄的类型向值域较宽的类型转换,方向如下:
char/short-> int-> unsigned ->long ->unsigned long-> long long ->unsigned long long ->float->double ->long double
注意:如果一个是long,一个是unsigned时,如果在该系统中long能表示unsigned的所有数(比较最大值),则将unsigned操作数转换为long,否则将两个都转换为unsigned long
(原因与整数提升中类似,在32位系统中unsigned与long长度相同,由于long带符号所以短了一半)
3、赋值转换
右操作数的值和类型完全由左操作数的值和类型决定
4、强制类型转换
(类型名)操作数 只对操作数(或表达式)的值进行类型转换,不干涉原有变量的类型和值