目录

运算符
运算符基础
算术运算符
关系(比较)运算符
逻辑运算符
位运算符
赋值运算符
三元运算符
流程控制
分支控制语句
赋值运算符


6 运算符

6.1 运算符基础

**运算符:**也称为操作符,是一种特殊的符号,用以用于数据的运算、赋值和比较等。

运算数: 也称为操作数,参与运算的数据,可以是变量、常量、表达式。

表达式: 表达式具有值,可以是一个变量、一个常量,也可以是变量、常量和运算符的组合。

运算符4要素: 功能、所需操作数个数、所组成表达式的值、有无副作用。

运算符分类(按操作数个数): 一元运算符、二元运算符、三元运算符。

运算符分类(按功能): 算术运算符、关系运算符、逻辑运算符、位运算符、赋值运算符、其他运算符

6.2 算术运算符

运算符 描述 操作数个数 所组成表达式的值 有无副作用
+ 正号 1 操作数的值
- 负号 1 操作数的值符号取反
+ 相加 2 相加的值
- 相减 2 相减的值
* 相乘 2 相乘的值
/ 相除 2 相除的值
% 取余(取模) 2 余数
++ 自增 1
-- 自减 1

总结:

  1. 正号、负号
  2. 加、减、乘、除
  3. 取余(取模)
    • 表达式的值的符号与第一个操作数保持一致。
    • 要求两个操作数必须都是整数。
  4. 自增、自减
    • 如果操作数在前,取操作数自增自减之前的值作为表达式的值(i++/i–)
    • 如果运算符在前,取操作数自增自减之后的值作为表达式的值(++i/–i)

注意:

  • 带有副作用的运算符,要求操作数必须是变量的形式。
  • C 语言规定,同一个表达中,不允许出现互相影响的带有副作用的子表达式(C 语言标准没有规定各个操作数的计算顺序,由编译器自行实现)。

6.3 关系(比较)运算符

运算符 描述 操作数个数 所组成表达式的值 有无副作用
> 大于 2 1或0
>= 大于等于 2 1或0
< 小于 2 1或0
<= 小于等于 2 1或0
== 相等 2 1或0
!= 不相等 2 1或0

总结:

  1. 比大小
  2. 判等

6.4 逻辑运算符

运算符 描述 操作数个数 所组成表达式的值 有无副作用
&& 逻辑与 2 两个条件都成立得1,否则得0
ll 逻辑或 2 只要一个条件成立就得1,都不成立得0
逻辑非 1 操作数非0表达式得0,操作数0表达式得1

注意:

逻辑与 短路:如果第一个条件不成立,第二个条件将不会执行到。

逻辑或 短路:如果第一个条件就成立,第二个条件将不会比执行。

6.5 位运算符

运算符 描述 操作数个数 所组成表达式的值 有无副作用
& 按位与 2 按位相同为1,否则为0
l 按位或 2 按位只要有一个为1,都为1
^ 按位异或 2 按位不同为1,否则为0
~ 按位取反 1 0变1,1变0
<< 按位左移 2 最低位补0
>> 按位右移 2 注意

总结:

  • 按位左移和右移的快捷计算方式:

注意:

  • 对于有符号数,如果最高位为1(负数),则右移时会在最高位补1。
    • ​ 如果最高位为0(正数),则右移时会在最高位补0。

6.6 赋值运算符

运算符 描述 操作数个数 所组成表达式的值 有无副作用
= 赋值 2 左边操作数的值
+= 相加赋值 2 左边操作数的值
-= 相减赋值 2 左边操作数的值
*= 相乘赋值 2 左边操作数的值
/= 相除赋值 2 左边操作数的值
%= 取余赋值 2 左边操作数的值
&= 按位与赋值 2 左边操作数的值
l= 按位或赋值 2 左边操作数的值
^= 按位异或赋值 2 左边操作数的值
<<= 左移赋值 2 左边操作数的值
>>= 右移赋值 2 左边操作数的值

总结:

c += 3; // 等价于 c = c + 3; 计算后c的值变为33

c += b; // 等价于 c = c + b; 计算后c的值变为53

a += 1.7; // 等价于 a = a + 1.7 计算后a的值变为11

注意:

(1)赋值运算符的第一个操作数(左值)必须是变量的形式,第二个操作数可以是任何形式的表达式。

(2)赋值运算符的副作用针对第一个操作数。

6.7 三元运算符

运算符 描述 操作数个数 所组成表达式的值 有无副作用
条件表达式? 表达式1: 表达式2; 3 注意

总结:

  1. a > b ? 1.1 : 1.2
  2. 若a>b为1.1,若a<b为1.2

注意:

(1)如果条件表达式为非0(真),整个表达式的值是表达式1;

(2)如果条件表达式为0(假),整个表达式的值是表达式2;

7 流程控制

7.1 分支控制语句

① 单向分支

1
2
3
4
5
6
7
if (条件表达式)  
{
语句1;
语句2;
...
语句n;
}

② 双向分支

1
2
3
4
5
6
7
8
9
10
11
12
13
14
if (条件表达式)  
{
语句1;
语句2;
...
语句n;
}
else
{
语句1;
语句2;
...
语句n;
}

③ 多向分支 else if

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
if (条件表达式1)  
{
语句1;
语句2;
...
语句n;
}
else if (条件表达式2)
{
语句1;
语句2;
...
语句n;
}
else if (条件表达式3)
{
语句1;
语句2;
...
语句n;
}
else if (条件表达式4)
{
语句1;
语句2;
...
语句n;
}
else
{
语句1;
语句2;
...
语句n;
}

④ 多向分支 switch case

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
switch (表达式)
{
case 表达式可能的值1
语句块;
break;
case 表达式可能的值2
语句块;
break;
case 表达式可能的值3
语句块;
break;
case 表达式可能的值4
语句块;
break;
default:
语句块;
}

注意:

(1)switch 后面表达式的值必须是一个整型(char、short, int, long等)或 枚举类型。

(2)case 后面的值必须是字面量常量,而不能是变量、标识符常量。

(3)default 是可选的,当没有匹配的 case 时,执行 default。

(4)break 语句可以使程序跳出 switch 语句块,如果没有break,会执行下一个case 语句块,直到遇到break或者执行到switch结尾,这个现象称为穿透。

⑤ 嵌套分支

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
if (条件表达式)  
{
if (条件表达式)
{
}
else
{

}
}
else
{
if (条件表达式)
{
}
else
{

}
}