分支结构
一、关系表达式
程序设计中需要经常对运算对象之间的大小进行比较,如:大小、相等等关系,这样的运算符称为关系运算符,用关系运算符将数值或表达式连接起来的式子就是关系表达式,满足关系表达式运算符关系的结果称为“真”,否则为假。
常用的关系运算符有:
关系运算符 | 含义 |
> | 大于 |
>= | 大于等于 |
< | 小于 |
<= | 小于等于 |
== | 等于 |
!= | 不等于 |
例5.1
5==3
这个关系表达式不满足运算符“==”的关系,其结果为假
注意:判断相等关系使用“==”,容易犯的错误是“=”那就成赋值语句了。
关系表达式的结果只有两种:真和假,真是非0(关系表达式为真是返回1),假是0(C++中引入了布尔数据类型,真为”True”,假为”False”)。
二、分支结构
顺序结构的程序中,程序按照语句顺序依次执行,但现实生活中需要根据情况进行判断,然后执行不同的操作,如:如果天下雨,就打伞,不下雨,就不打伞。
1、if语句
单分支if语句
形式一:if(表达式p) 语句a;
或
if(表达式p)
语句a;
形式二:
if(表达式p)
{
语句块a
}
如果表达式p为真,则执行语句a或语句块a。
注意点:对于形式一,语句a可以直接写在if语句后面,也可以换行写在下一行,但if语句后面不能有”;”,否则代表语句结束,如果有多条语句需要使用“{}”包裹,否则,只执行第一句。
例5.2
#include <stdio.h>
int main()
{
int day;
scanf("%d",&day);
if(day==1) printf("今天是%d日",day);
return 0;
}
输入:1
输出:今天是1日
双分支if语句
形式一:
if(表达式p)
{
语句块a
}
else
{
语句块b
}
形式二:
if(表达式p) 语句a;
else 语句b;
表达式p为真时,执行语句块a或语句a内容,否则,执行语句块b或语句b内容。
例5.3
#include <stdio.h>
int main()
{
int a,b;
scanf("%d%d",&a,&b);
if(a>b)
printf("最大数是%d",a);
else
printf("最大数是%d",b);
return 0;
}
输入:23 89
输出:最大数是89
例5.4
#include <stdio.h>
int main()
{
double a,b;
double c,d;
double esp=0.000001;
printf("输入两个实数:");
scanf("%lf%lf",&a,&b);
printf("输入另外两个实数:");
scanf("%lf%lf",&c,&d);
if((a/b-c/d)<esp)
{
printf("两个数的比值相等\n");
printf("输入的数据是:a=%.2f,b=%.2f,c=%.2f,d=%.2f\n",a,b,c,d);
}
else
{
printf("两个数的比值不相等\n");
printf("输入的数据是:a=%.2f,b=%.2f,c=%.2f,d=%.2f\n",a,b,c,d);
}
return 0;
}
输入:
输入两个实数:1 3
输入另外两个实数:2 6
输出:
两个数的比值相等
输入的数据是:a=1.00,b=3.00f,c=2.00,d=6.00
注意点:对于两个浮点数相等的比较,由于浮点数表示精度问题,不能简单的使用“==”判断,在比较的时候需要用一个很小的数值来进行比较,当二者之差小于这个很小的数时,就认为二者是相等了。
多分支if语句
形式一:
if(表达式p1)
{
语句块a
}
else if(表达式p2)
{
语句块b
}
else if(表达式p3)
{
语句块c
}
.
.
else
{
语句块z
}
形式二:
if(表达式p1) 语句a;
else if(表达式p2) 语句b;
else if(表达式p3) 语句c
.
.
else 语句z;
执行情况:
表达式p1为真,执行语句a或语句块a,否则,表达式p2为真,执行语句b或语句块b,否则,表达式p3为真,执行语句c或语句块c,依次执行,所有表达式都不为真,执行语句z或语句块z。
例5.5
分支语句嵌套
if(表达式p1)
{
if(表达式p2)
{
语句块a
}
else
{
语句块b
}
}
else
{
if(表达式p3)
{
语句块c
}
else
{
语句块d
}
}
执行情况:
如果表达式p1为真,判断表达式p2是否为真,“真”执行语句块a,”假”执行语句块b;
如果表达式p1为假,判断表达式p2是否为真,“真”执行语句块c,”假”执行语句块d。
注意点:如果存在else子句,必须有匹配的if语句。
例5.5
成绩90以上(含)为A,80—90为B,70—80为C,60-70为D,小于60为E
#include <stdio.h>
int main()
{
double a;
scanf("%lf",&a);
if(a>=90) printf("A");
else if(a>=80) printf("B");
else if(a>=70) printf("C");
else if(a>=60) printf("D");
else printf("E");
return 0;
}
输入
91.2
输出
A
输入
59.9
输出
E
2、switch语句
从上面例子可以看出,处理多个分支使用if语句不很清晰,这时可以使用switch语句。
语句结构:
switch(表达式p)
{
case 常量1:
语句块1
break;
case 常量2:
语句块2
break;
..
….
case 常量n:
语句块n
break;
default:
语句块n+1
}
语句执行:
先计算表达式p的值,然后与常量比较,与哪个相等执行相应语句块,遇到break中止执行,跳出switch语句,没有相等执行default语句,没有default语句则执行到”}”结束switch语句。
注意点:表达式p的值,必须与常量数据类型一致,且必须为整型(含char型)。
例5.6
#include <stdio.h>
int main()
{
char a;
scanf("%c",&a);
switch(a)
{
case 'A':
printf("A\n");
printf("very good\n");
break;
case 'B':
printf("B\n");
printf("good\n");
break; //1
case 'C':
printf("C\n");
break;
default:
printf("E\n");
}
return 0;
}
输入:
C
输出
C
输入
b
输出
E
注意点:
如果忽略break语句,程序找到匹配常量后,执行相应语句块,直到遇到break或”}”,如:去掉1行的break,输入B,输出
B
good
C
忽略与常量’C’的比较,直接执行’C’的语句块。
三、逻辑表达式
在上面分支语句中的表达式都是关系表达式,有时多个关系表达式组合起来更有用,这时需要逻辑运算符将关系表达式连接起来,用逻辑运算符连接运算对象组成的表达式就是逻辑表达式。
表一:逻辑运算符
运算符 | 含义 |
&& | 逻辑与 |
|| | 逻辑或 |
! | 逻辑非(单目运算符) |
逻辑表达式运算结果:
a&&b 只有a和b都是真时,表达式结果为真,有一个为假,表达式结果为假。
a||b a或b有一个为真,表达式结果为真,a和b都为假,表达式结果为假。
!a a为真时,表达式结果为假,a为假时,表达式结果为真。
例5.7
成绩90以上(含)为A,80—90为B,70—80为C,60-70为D,小于60为E
#include <stdio.h>
int main()
{
double a;
scanf("%lf",&a);
if(a>=90) printf("A");
if(a>=80&&a<90) printf("B");
if(a>=70&&a<80) printf("C");
if(a>=60&&a<70) printf("D");
if(a<60) printf("E");
return 0;
}
输入
91.2
输出
A
输入
59.9
输出
E
四、位运算
在C语言中可以单独操控变量中的位,位运算就是对变量中的位进行查询、设置、移位等操作,只能对整型数据(含char型)操作。
表一
位运算符 | 含义 |
& | 按位与 |
| | 按位或 |
~ | 按位取反 |
^ | 按位异或 |
<< | 左移位 |
>> | 右移位 |
按位操作是对变量的位进行的,所以操作数只有“0”和“1”。
表二 位运算符的运算规则
a | b | a&b | a|b | a^b | ~a |
1 | 1 | 1 | 1 | 0 | 0 |
1 | 0 | 0 | 1 | 1 | 0 |
0 | 1 | 0 | 1 | 1 | 1 |
0 | 0 | 0 | 0 | 0 | 1 |
按位操作,不改变原对象的值,如果改变原值,需要把变化后的结果赋值给原对象,如:
val=val&2;
复合运算符:&=、|=、~=、 ^=、 <<=、 >>=
注意与逻辑运算符的区别,逻辑表达式结果只有真假,位运算是实际数值。
1、移位运算<<
变量<<n
左移运算将运算对象左移n位,左端自然移除,右端补0,有符号数、无符号数都一样。
2、移位运算>>
变量>>n
右移运算将运算对象右移n位,右端自然移除,有符号数正数、无符号数左端补0,有符号数负数左端补1。
例5.8
#include <stdio.h>
int main()
{
char a;
a=-127;
printf("%x\n",a);
a=a<<1;
printf("%x\n",a);
return 0;
}
输出
81
2
五、条件运算符和条件表达式
条件运算符是C语言中唯一的一个三目运算符,它需要三个操作数,条件表达式为:
表达式1?表达式2:表达式3。
? : 称为条件运算符
执行情况:
先计算表达式1的值,若为真,则整个表达式的值为表达式2的值,否则,为表达式3的值。
当有多个条件表达式组成的符合条件表达式时,运算顺序从右向左。
如:a>b?a:c>d?c:d相当于a>b?a:(c>d?c:d)
例5.9
#include <stdio.h>
int main()
{
int a,b,max;
scanf("%d%d",&a,&b);
max=a>b?a:b;
printf("max=%d\n",max);
return 0;
}
输入:
3 5
输出
max=5
六、逗号运算符和逗号表达式
逗号运算符是特殊的运算符,将两个表达式连接起来,一般形式:
表达式1,表达式2
执行情况:先求解表达式1,再求解表达式2,最后的结果是表达式2的值。
例5.10
a=(b=5,b-2)
a的值为3
表达式可以是多个表达式,结合性是左结合性。
七、运算符优先级
优先级 | 运算符 | 含义 | 使用形式 | 结合方向 |
1 | [] | 数组下标 | 数组名[常量表达式] | 从左到右 |
() | 圆括号 | (表达式) 函数名(形参表) | ||
. | 成员选择(对象) | 对象.成员名 | ||
-> | 成员选择(指针) | 对象指针->成员名 | ||
2 | - | 负号运算符 | -表达式 | 从右到左 |
~ | 按位取反 | ~表达式 | ||
++ | 自增 | ++变量、变量++ | ||
-- | 自减 | --变量、变量-- | ||
* | 取值运算符 | *指针变量 | ||
& | 取地址 | &变量 | ||
! | 逻辑非 | !表达式 | ||
(类型) | 强制类型转换 | (数据类型)表达式 | ||
sizeof | 长度运算符 | sizeof(表达式) | ||
3 | * | 乘 | a*b | 从左到右 |
/ | 除 | a/b | ||
% | 取余数 | a%b | ||
4 | + | 加 | a+b | 从左到右 |
- | 减 | a-b | ||
5 | << | 左移 | 变量<<表达式 | 从左到右 |
>> | 右移 | 变量>>表达式 | ||
6 | > | 大于 | a>b | 从左到右 |
>= | 大于等于 | a>=b | ||
< | 小于 | a<b | ||
<= | 小于等于 | a<=b | ||
7 | == | 等于 | a==b | 从左到右 |
!= | 不等于 | a!=b | ||
8 | & | 按位与 | a&b | 从左到右 |
9 | ^ | 按位异或 | a^b | 从左到右 |
10 | | | 按位或 | a|b | 从左到右 |
11 | && | 逻辑与 | a&&b | 从左到右 |
12 | || | 逻辑或 | a||b | 从左到右 |
13 | ? : | 条件运算符 | 表达式1?表达式2:表达式3 | 从右到左 |
14 | = | 赋值运算符 | 从右到左 | |
+= | 加后赋值 | |||
-= | 减后赋值 | |||
/= | 除后赋值 | |||
*= | 乘后赋值 | |||
%= | 取余后赋值 | |||
&= | 按位与后赋值 | |||
|= | 按位或后赋值 | |||
^= | 按位异或后赋值 | |||
>>= | 右移后赋值 | |||
<<= | 左移后赋值 | |||
15 | , | 逗号运算符 | 从左到右 |