5.1 关系运算符和表达式
比较两个量的运算符称之为关系运算符。
5.1.1 关系运算符及其优先次序
在C语言中有如下关系运算符:
<
小于<=
小于或等于>
大于>=
大于或等于==
等于!=
不等于
关系运算符的特点:
- 关系运算符都是双目运算符,其结合性均为左结合(从左向右运算)。
- 关系运算符的优先级低于算术运算符,高于赋值运算符。
- 在六个关系运算符中,<,<=,>,>=的优先级相同,高于==和!=,==和!=的优先级相同。
5.1.2 关系表达式
关系表达式的基本格式:表达式 关系运算符 表达式
。如a+b>c-d
、-i-5*j==k+1
等。
#include <stdio.h>
#include <math.h>
int main() {
int m = 3, n = 5;
int x = m < n;
int y = m == n;
printf("x=%d, y=%d\n", x, y);// x=1, y=0
// 字符变量是以它对应的ASCII码参与运算的
char c = 'A';
printf("%d,%d\n", c > 12, c > 'B');// 1,0
// 对于含多个关系运算符的表达式,根据运算符的左结合性,从左往右运算
// 先计算k==j,该式子不成立得到0,再计算0==i+5,也不成立,故最后的结果为0
int i = 1, j = 2, k = 3;
printf("%d", k == j == i + 5);// 0
}
注意:
- 关系表达式可以出现嵌套的情况,如
a>(b>c)
、a!=(c==d)
等。 - 关系表达式的值是“真”和“假”,分别用“1”和“0”表示。如
5>0
的值为真即为1;如3>5
的值为假即为0。
5.2 逻辑运算符和表达式
5.2.1 逻辑运算符及其优先次序
C语言中提供了三种逻辑运算符:
&&
:与运算||
:或运算!
:非运算
逻辑运算符的特点:
- 与运算符
&&
和或运算符||
均为双目运算符,具有左结合性。 - 非运算符
!
为单目运算符,具有右结合性。 - 逻辑运算符的优先级关系如下:
! -> && -> ||
。在逻辑运算符中!
优先级最高,||
优先级最低。 - 逻辑运算符与其他运算符的优先级关系如下:
!(非) -> 算术运算符 -> 关系运算符 -> &&和|| -> 赋值运算符
。其中!
优先级最高。 - 如
a>b && c>d
等价于(a>b)&&(c>d)
;如!b==c||d<a
等价于((!b)==c)||(d<a)
。 - 但不推荐上面的写法,更推荐使用小括号来表示它们的优先级情况。
5.2.2 逻辑运算的值
**逻辑运算的值也为“真”和“假”两种,用“1”和“0 ”来表示。**它的规则如下:
运算符 | 说明 | 示例 | |
---|---|---|---|
与运算 | && | 参与运算的两个量都为真时,结果才为真,否则为假。 | 5>0 && 4>2 返回1 |
或运算 | || | 参与运算的两个量只要有一个为真,结果就为真。 两个量都为假时,结果为假。 | 5>0 || 5>8 返回1 |
非运算 | ! | 参与运算量为真时,结果为假;参与运算量为假时,结果为真。 | !(5>0) 返回0 |
注意:
- 虽然C编译在给出逻辑运算值时,以“1”代表“真”,“0 ”代表“假”。但反过来在判断一个量是为“真”还是为“假”时,以“0”代表“假”,以非“0”的数值作为“真”。如由于5和3均为非“0”因此
5&&3
的值为“真”,即为1;如5||0
的值为“真”,即为1。
5.2.3 逻辑表达式
逻辑表达式的基本格式如下:表达式 逻辑运算符 表达式
。特点如下:
- 逻辑表达式中的表达式又可以是逻辑表达式,从而形成嵌套,如
(a&&b)&&c
根据逻辑运算符的左结合性可以写成a&&b&&c
。 - 逻辑表达式的值是式中各种逻辑运算的最后值,以“1”和“0”分别代表“真”和“假”。
示例如下:
#include <stdio.h>
int main() {
int i = 10, j = 15;
printf("%d\n", i && j);// 1
printf("%d\n", i || j);// 1
printf("%d\n", !j);// 0
printf("%d\n", i && 0);// 0
printf("%d\n", i || 0);// 1
printf("%d\n", !0);// 1
}
5.3 if语句
5.3.1 if语句的三种形式
5.3.1.1 第一种形式,if
第一种形式语法如下:
if(表达式) 语句;
语义:如果表达式的值为真,则执行其后的语句, 否则不执行该语句。
示例:
#include <stdio.h>
int main() {
int i = 20, j = 15;
if (i > j) printf("i>j");// i>j
if (i == j) printf("i==j");// 不会被执行
}
5.3.1.2 第二种形式,if-else
第二种形式语法如下:
if(表达式)
语句1;
else
语句2;
语义:如果表达式的值为真,则执行语句1,否则执行语句2 。
示例:
#include <stdio.h>
int main() {
int i = 20, j = 15;
if (i == j)
printf("i==j");
else
printf("i!=j");
}
5.3.1.3 第三种形式,if-else-if形式
前二种形式的if语句一般都用于两个分支的情况。当有多个分支选择时,可采用if-else-if语句,其一般形式为:
if(表达式1)
语句1;
else if(表达式2)
语句2;
else if(表达式3)
语句3;
...
else if(表达式m)
语句m;
else
语句n;
语义:依次判断表达式的值,当出现某个值为真时,则执行其对应的语句。然后跳到整个if语句之外继续执行程序。 如果所有的表达式均为假,则执行语句n。然后继续执行后续程序。
示例:
#include <stdio.h>
int main() {
int i = 20, j = 15;
if (i > j)
printf("i>j");
else if (i == j)
printf("i==j");
else
printf("i<j");
}
5.3.1.4 if语句使用的注意事项
- if语句中,if关键字之后均为表达式,该表达式可以是逻辑表达式或关系表达式,还可以是其他表达式如赋值表达式,甚至可以是一个变量。只要表达式的值永远非零,那么其后的语句就会被执行。
#include <stdio.h>
int main() {
// if语句中表达式是逻辑表达式
if ((3 > 2) && (2 && 1))
printf("逻辑表达式");
// if语句中表达式是关系表达式
if (3 > 2)
printf("关系表达式");
// if语句中表达式是赋值表达式
int a;
if (a = 3)
printf("赋值表达式");
// if语句中表达式是一个变量
int b = 11;
if (b)
printf("变量");
}
-
在if语句中,条件判断表达式必须用括号括起来,在语句之后必须加分号。
-
在if语句的三种形式中,所有的语句应为单个语句,如果要想在满足条件时执行一组(多个)语句,则必须把这一组语句用
{}
括起来组成一个复合语句。但要注意的是在}
之后不能再加分号。
#include <stdio.h>
int main() {
int i = 10, j = 5;
// 多条语句用{}括起来
if (i > j) {
printf("i>j\n");
printf("i=%d\n", i);
} else {
printf("i<=j\n");
printf("j=%d\n", j);
}
}
5.3.2 if语句的嵌套
if语句的执行语句中还可以有if语句,如下:
if(表达式1)
if(表达式2)
语句1:
else
语句2:
注意:C语言规定,else 总是与它前面最近的if配对。示例如下:
#include <stdio.h>
int main() {
int i = 10, j = 5;
if (i != j)
if (i > j)
printf("i>j");
else
printf("i<j");
else
printf("i==j");
}
建议使用{}
来分隔执行语句,可读性更强:
#include <stdio.h>
int main() {
int i = 10, j = 5;
if (i != j) {
if (i > j) {
printf("i>j");
} else {
printf("i<j");
}
} else {
printf("i==j");
}
}
5.3.3 条件运算符和条件表达式
条件运算符为?
和:
,它是一个三目运算符,即有三个参与运算的量。由条件运算符组成条件表达式的一般形式为:表达式1 ? 表达式2 : 表达式3
。其求值规则为:如果表达式1的值为真,则以表达式2 的值作为条件表达式的值,否则以表达式2的值作为整个条件表达式的值。条件表达式通常用于赋值语句之中。如有条件语句:
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)
。
示例如下:
#include <stdio.h>
int main() {
int i = 10, j = 5, max;
// 使用if语句
if (i > j) {
max = i;
} else {
max = j;
}
// 使用条件表达式
max = i > j ? i : j;
}
5.4 switch语句
C语言还提供了另一种用于多分支选择的switch语句, 其一般形式为:
switch(表达式){
case 常量表达式1:
语句1;
break;
case 常量表达式2:
语句2;
break;
...
case 常量表达式n:
语句n;
break;
default:
语句n+1;
}
语义:计算表达式的值。 并逐个与其后的常量表达式值相比较,当表达式的值与某个常量表达式的值相等时,即执行其后的语句,然后不再进行判断,继续执行后面所有case后的语句。如表达式的值与所有case后的常量表达式均不相同时,则执行default后的语句。
示例:
#include <stdio.h>
int main() {
int day;
printf("input integer day[1-7]: \n");
scanf("%d", &day);
switch (day) {
case 1:
printf("星期一");
break;
case 2:
printf("星期二");
break;
case 3:
printf("星期三");
break;
case 4:
printf("星期四");
break;
case 5:
printf("星期五");
break;
case 6:
printf("星期六");
break;
case 7:
printf("星期天");
break;
default:
printf("请输入正确的数字");
}
}
使用switch语句的注意事项:
- 在case后的各常量表达式的值不能相同,否则会出现错误。
- 在case后,允许有多个语句,可以不用{}括起来。
- 各case和default子句的先后顺序可以变动,而不会影响程序执行结果。
- default子句可以省略不用。
- 如果没有break语句则跳到匹配的case语句之后,仍然会执行后面的语句,所以需要break关键字自动跳出switch语句。break语句,专用于跳出switch语句,break 语句只有关键字break,没有参数。