知识点
#4.1 关系运算符, 关系表达式与逻辑运算符, 逻辑表达式
#- @ 关系与逻辑运算图
- ![[白板/P6 关系与逻辑运算.canvas|P6 关系与逻辑运算]]
4.1.1 关系运算符和关系表达式
#关系运算符
#- @ 关系运算: 又称比较运算,将两个值进行比较,判断比较结果是否符合给定条件
- C 语言提供了 6 种关系运算符
| 编号 | 关系运算符 | 含义 | 优先级 |
|---|
| 1 | < | 小于 | 高(前四个优先级相同) |
| 2 | <= | 小于或等于 | 高 |
| 3 | > | 大于 | 高 |
| 4 | >= | 大于或等于 | 高 |
| 5 | == | 等于 | 低(后两个优先级相同) |
| 6 | != | 不等于 | 低 |
关系运算符优先级要点
#- ! 前四个关系运算符优先级相同,后两个优先级也相同,前四个高于后两个
- ! 关系运算符优先级低于算术运算符
- ! 关系运算符优先级高于赋值运算符
- !
== 是两个等号,千万不能写成一个等号 =,否则变成赋值运算符
三种运算符优先级关系
#高 算术运算符
关系运算符
低 赋值运算符
表达式范例
#c > a+b // 等价于 c > (a+b),关系运算符优先级低于算术运算符 "+"
a > b == c // 等价于 (a>b) == c,">" 优先级高于 "=="
a == b < c // 等价于 a == (b<c),"<" 优先级高于 "=="
a = b > c // 等价于 a = (b>c),赋值运算符优先级低于关系运算符 ">"
关系表达式
#- @ 关系表达式: 用关系运算符将两个表达式连接起来的式子
- ! 关系表达式的值是一个逻辑值,即"真"或"假"
- ! 在 C 语言中,“真"用
true 表示,也可以用 1 表示;“假"用 false 表示,也可以用 0 表示 - ! 关系表达式的结果值是
0 或 1
printf("5>3的值为%d\n", 5>3); // 5>3的值为1
if(true == 1)
printf("true==1\n"); // 这行被执行
else
printf("true!=1\n");
// 如果 a=3, b=2, c=1
// (a>b) == c 为真,因为 a>b 的值为1,等于 c 的值
// b+c < a 为假,因为 b+c 的值为3,并不小于 a
4.1.2 逻辑运算符和逻辑表达式
#逻辑运算符
#| 编号 | 逻辑运算符 | 含义 | 运算分量 |
|---|
| 1 | && | 逻辑与(and) | 双目 |
| 2 | || | 逻辑或(or) | 双目 |
| 3 | ! | 逻辑非(not) | 单目 |
逻辑运算规则
#- !
&& 全真出真,有假出假:两个运算分量必须全为真,结果才为真 - !
\|\| 有真出真,全假出假:只要有一个为真,结果就为真 - !
! 取反:原来为真变假,原来为假变真
逻辑运算真值表
#a | b | !a | !b | a&&b | a||b |
|---|
| 真 | 真 | 假 | 假 | 真 | 真 |
| 真 | 假 | 假 | 真 | 假 | 真 |
| 假 | 真 | 真 | 假 | 假 | 真 |
| 假 | 假 | 真 | 真 | 假 | 假 |
逻辑运算符易错点
#- ! 千万不要把
&& 写成 &(位运算符),程序可能不报错但结果不对 - ! 千万不要把
\|\| 写成 \|(位运算符),同样程序可能不报错但结果不对 - ! 进行逻辑判断时,不等于 0 的数值全部被认为是
true - ! 系统给出的逻辑运算结果不是
0(假)就是 1(真),不可能是其他数值 - ! 作为参加逻辑运算的对象,是
0 就表示假,非 0 就表示真
printf("4==true,结果为%d\n", 4==true); // 0(假),4不等于1
printf("1==true,结果为%d\n", 1==true); // 1(真)
printf("4&&5,结果为%d\n", 4&&5); // 1(真),4和5都是非0,都为真
逻辑运算符优先级
#| 优先级(数字越小越高) | 运算符 |
|---|
| 1 | 逻辑非 ! |
| 2 | 算术运算符 |
| 3 | 关系运算符 |
| 4 | && 和 || |
| 5 | 赋值运算符 |
- ! 逻辑运算符中的
&& 和 \|\| 优先级低于关系运算符 - ! 逻辑运算符中的
! 优先级高于算术运算符
a>b && x>y // 等价于 (a>b) && (x>y)
a==b \|\| x==y // 等价于 (a==b) \|\| (x==y)
!a \|\| a>b // 等价于 (!a) \|\| (a>b)
'c' && 'd' // 比较的是字符的ASCII码,都不为0,结果为真
短路求值
#- @ 短路求值: 只要最终的结果已经可以确定是真或假,求值过程便宣告终止
- ! 这是面试常考的陷阱
&& 短路求值:
- 只有
a 为真才需要判断 b,只有 a 和 b 都为真才需要判断 c - 只要
a 为假,就不必判断 b 和 c
int a = 6;
if(3<5 && (a=8)) // 3<5为真,继续执行 a=8,a = 8
printf("a = %d\n", a); // a = 8
int a = 6;
if(3>5 && (a=8)) // 3>5为假,短路!a=8 不被执行
printf("a = %d\n", a);
printf("a = %d\n", a); // a = 6
\|\| 短路求值:
- 只要
a 为真就不必判断 b 和 c - 只有
a 为假才需要判断 b
int a = 6;
if(3>5 \|\| (a=8)) // 3>5为假,继续执行 a=8,a = 8
printf("a = %d\n", a); // a = 8
int a = 6;
if(3<5 \|\| (a=8)) // 3<5为真,短路!a=8 不被执行
printf("a = %d\n", a);
printf("a = %d\n", a); // a = 6
4.2 if 语句详解
#- @ if语句图
- ![[白板/P7 if语句.canvas|P7 if语句]]
4.2.1 if 语句的三种形式
#第一种形式
#- 含义:如果判断表达式中的条件满足,则执行对应的语句,否则直接跳过
int x = 8;
if(x > 5)
printf("x值>5\n"); // x值>5
// 执行多条语句必须用 {} 构成复合语句
int x = 8;
if(x > 5) {
printf("x值>5\n"); // x值>5
printf("x值确实>5\n"); // x值确实>5
}
- ! 如果不用
{},if 语句在条件成立时只会执行 if 后面第一次遇到分号之前的语句 - !
{} 后面没有分号
int x = 8;
if(x > 5)
printf("x值>5\n"); // 属于if
printf("x值确实>5\n"); // 不属于if!不管条件是否成立都会执行
第二种形式
#int x = 5, y = 2;
if(x > y)
printf("x>y是OK的\n"); // 这行被执行
else
printf("x>y不OK\n"); // 这行不会被执行
- ! 多条语句必须用
{} 括起来,否则会产生语法错误
// 错误写法!第二个printf导致if和else之间夹了不该出现的语句
int x = 5, y = 2;
if(x > y)
printf("x>y是OK的1\n");
printf("x>y是OK的2\n"); // 这行会导致语法错误
else
printf("x>y不OK1\n");
第三种形式
#if(判断表达式1) 语句1;
else if(判断表达式2) 语句2;
else if(判断表达式3) 语句3;
else if(判断表达式m) 语句m;
else 语句n;
- 含义:从上到下依次判断,哪个条件成立就执行对应的语句,都不成立则执行
else 的语句
int number = 380;
int cost = 0;
if(number > 500)
cost = 1;
else if(number > 300) // 本条件成立
cost = 2; // 这行被执行
else if(number > 100)
cost = 3;
else
cost = 4;
- ! 最后一个
else 可以省略,省略后如果所有条件都不成立,if 语句不执行任何代码
if 语句说明
#- ! 判断表达式一般为逻辑表达式或关系表达式
- ! 判断表达式的值为
0 按"假"处理,非 0 按"真"处理 - !
if 语句可以单独使用,但 else 语句不能单独使用,必须与 if 配对
if(15) // 条件成立,15非0
printf("成立哦\n"); // 本条语句会被执行
if('a') // 条件成立,'a'的ASCII码非0
printf("条件为真哦\n"); // 本条语句会被执行
4.2.2 if 语句的嵌套
#- @
if 嵌套: 在 if 语句中包含一个或多个 if 语句 - !
else 总是跟它上面最近的尚未配对的 if 进行配对,不要被代码对齐所迷惑
int x = 5;
if(x > 1)
if(x > 8)
printf("x>8\n");
else // 这个else和第二个if配对!不是和第一个if
if(x > 3)
printf("x>3\n");
else
printf("x为其他值\n");
int x = 5;
if(x > 3) {
if(x > 4)
printf("x>4\n"); // 这个printf语句会被执行
} else {
printf("执行else\n");
}
4.3 条件运算符和 switch 语句
#- @ 条件与switch图
- ![[白板/P8 条件与switch.canvas|P8 条件与switch]]
4.3.1 条件运算符
#[!tip] 条件运算符
- @ 条件运算符:
? :,C 语言中唯一的三目运算符 - 一般形式:
表达式1 ? 表达式2 : 表达式3 - 执行流程: 先求解表达式1,若为真则取表达式2的值,否则取表达式3的值
// 用if语句
int a = 4, b = 5, max;
if(a > b)
max = a;
else
max = b;
// 用条件运算符(等价写法)
max = (a > b) ? a : b;
- ! 条件运算符优先级高于赋值运算符
- ! 条件运算符优先级低于关系运算符,所以
max = (a>b) ? a : b 可以写成 max = a>b ? a : b - ! 条件运算符结合顺序是从右到左
a>b ? a : c>d ? c : d // 等价于 a>b ? a : (c>d ? c : d)
4.3.2 switch 语句
#[!tip] switch 语句
- @
switch 语句: 用于处理多分支选择,可读性比多个 else if 更好 - 格式:
switch(表达式) {
case 常量表达式1:
语句;
break;
case 常量表达式2:
语句;
break;
default:
语句;
break;
}
int abc = 3;
switch(abc) {
case 1:
printf("值为1\n");
break;
case 2:
printf("值为2\n");
break;
case 3:
printf("值为3\n"); // 这行会被执行
break;
default:
break;
}
switch 语句要点
#| 要点 | 说明 |
|---|
| 表达式类型 | 可以是整型、字符型、枚举型表达式 |
case 值互不相同 | 每个 case 后的常量表达式值必须互不相同,否则编译错误 |
| 顺序无关 | 各 case 之间、case 和 default 之间的顺序没有影响 |
break 不可省略 | 绝不要忘记 break,否则会继续执行下一个 case |
default 可省略 | 省略后所有 case 不满足时整个 switch 不执行 |
忘记 break 的后果
#- ! 如果在一个
case 的最后不加 break,程序执行流程会继续执行下一个 case 中的语句,而不管该 case 条件是否满足 - ! 程序执行流程从满足条件的
case 作为入口一直执行下去,除非遇到 break 或整个 switch 执行完毕
int tees = 1;
switch(tees) {
case 1:
printf("值为1\n"); // 这行会被执行
// 这里漏掉了 break!
case 2:
printf("值为2\n"); // 漏掉break的后果:这行也会被执行!
break;
case 3:
printf("值为3\n");
break;
default:
break;
}
// 输出: 值为1 值为2
多个 case 共用执行语句
#case 3:
case 4:
printf("值为3或者4\n"); // switch后表达式的值为3或4都执行这行代码
break;
case 中多行语句
#- !
case 中如果包含多行语句,不需要使用 {} 将多行语句括在一起
case 2:
printf("值为2\n");
printf("值为2\n");
printf("值为2\n");
break;
Reply by Email