选择与循环
# 选择与循环
# 选择结构程序设计
我们了解到算术运算符的优先级高于关系运算符、关系运算符的优先级高于逻辑与和逻辑或运算符、相同优 先级的运算符从左至右进行结合等,那么表达式 5>3&&8<4-!0 的最终值是多少

# if 语句
我们用 if 判断语句来实现这 样的效果:if 判断条件(表达式)为真,就执行某个语句,反之不执行这个语句。
下面来看一个判断输入值是否大于 0 的例子。

if 后面不能加分号,因为如 果有 else 分支语句,那么加分号会导致编译不通过;
if(); //会导致编译不通过 无论任何这个if语句都不执行
if(){
}
2
3
4
if 语句和 else 语句也可以多个同时使用(多分支语句),但是,无论有多少个 if 语句或 else if 语句,程序都只会执行其中的一个语句。

同时,if 语句也支持多层嵌套,在 if 语句中又包含一个或多个 if 语句称为 if 语句的嵌套

if (number>500)cost=0.15;
else if(number>300)cost=0.10;
else if(number>100)cost=0.075;
else if(number>50)cost=0.05;
else cost=0;
2
3
4
5
使用 if 嵌套语句时,要考虑 “悬空的 else” 问题。例如,在下面的例子中,else 子句从属于哪个 if 语句?
if(i>1)
if(i<10)
printf("i>1 and i<10\n");
else
printf("no,they are not\n");
2
3
4
5
和其他绝大多数语言一样,C 语言中的 else 子句从属于最靠近它的不完整的 if 语句。上例 中的 else 子句从属于第二个 if 语句,如果想让它从属于第一个 if 语句,那么可以用一个花括 号把第二个 if 语句包含在一个单独的代码块内,如下所示。
if(i>1){
if(i<10)
printf("i>1 and i<10\n");
}
else
printf("no,they are not\n");
2
3
4
5
6
在 if 语句中的语句列表前后加上花括号,可以防止不小心加了一句代码后,使实际未被包含的语句被包含在某个 if 语句中的错误。
# switch 语句
判断的一个变量可以等于几个值或几十个值时,使用 if 和 else if 语句会导致 else if 分支非常多,这时可以考虑使用 switch 语句,switch 语句的语法格式如下:
switch (表达式)
{case 常量表达式 1:语句 1
case 常量表达式 2:语句 2
…
case 常量表达式n:语句 n
default :语句 n+1
}
2
3
4
5
6
7
switch 语句匹配并不需要常量表达式的值有序排列, 输入值等于哪个常量表达式的值,就执行其后的语句,每条语句后需要加上 break 语句,代表匹 配成功一个常量表达式时就不再匹配并跳出 switch 语句。
int main()
{
int mon, year;
while (scanf("%d%d", &year, &mon) != EOF)
{
switch (mon)
{
case 2:
printf("mon=%d is %d days\n", mon, 28 + (year % 4 == 0 && year % 100 != 0 || year % 400 == 0));
break;
case 1:
printf("mon=%d is 31days\n", mon);
break;
case 3:
printf("mon=%d is 31days\n", mon);
break;
case 5:
printf("mon=%d is 31days\n", mon);
break;
case 7:
printf("mon=%d is 31days\n", mon);
break;
case 8:
printf("mon=%d is 31days\n", mon);
break;
case 10:
printf("mon=%d is 31days\n", mon);
break;
case 12:
printf("mon=%d is 31days\n", mon);
break;
case 4:
printf("mon=%d is 30days\n", mon);
break;
case 6:
printf("mon=%d is 30days\n", mon);
break;
case 9:
printf("mon=%d is 30days\n", mon);
break;
case 11:
printf("mon=%d is 30days\n", mon);
break;
default:
printf("error mon\n");
}
}
system("pause");
return 0;
}
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
如果一个 case 语句后面没有 break 语句,那么程序会继续匹配下面的 case 常量表达式。
# 循环结构程序设计
# goto 语句
市面上很多参考书都告诉读者不用掌握 goto 语句,这种说法其实是不对的。goto 语句对应着汇编语言中的 jmp 跳转,体现了循环结构的本质。C 语言中的 while、do while 和 for 循环在 程序编译时,都要拆解为汇编语言中的 jmp 跳转。goto 语句也被称为无条件转向语句,具体语 句格式为 “goto 语句标号;”,语句标号的命名规则与 C 语言中变量的命名规则一致,例如,“goto label_1;” 这种写法是合法的,而 “goto 123;” 这种写法是不合法的。goto 语句的使用场景 分为两种:一种是向上跳转实现循环,另一种是向下跳转实现中间的部分代码不执行。
下面来看使用 goto 语句向上跳转计算 1 到 100 之间所有整数之和的例子,如下面代码块所示。 因为 goto 语句是无条件跳转的,所以我们配合使用 if 语句和 goto 语句,通过 if 语句进行判断, 当 i 大于 100 时就不再进行无条件跳转,所以在 goto lable 与 lable 之间需要执行自增操作 i++, 让判断趋近于假。如果 i 小于等于 100,那么代码执行到第 9 行时,就会跳转到第 4 行再次开 始执行。
int main()
{
int i = 1, sum = 0;
lable:
sum += i;
i++;
if (i <= 100)
{
goto lable;
}
printf("sum=%d\n", sum);
system("pause");
}
2
3
4
5
6
7
8
9
10
11
12
13
下面来看 goto 语句向下跳转实现中间的部分代码不执行的例子,如图 3.2.2 所示。判断 disk 的输入值为 0 时,代表磁盘发生异常,此时直接跳转到第 15 行的 “lable_disk_error:” 继续执 行。在编写 Linux 内核时会大量采用这种手法,因为这样编写不仅会降低代码的编写难度,而且 会提升代码编译和执行的效率。
int main()
{
int disk;
scanf("%d",&disk);
if(disk==0)
{
goto lable_disk_error;
}
//写磁盘的操作
lable_disk_error:
printf("system is error\n")
system("pause"):
return 0;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
# while 循环
while 语句用来实现 “当型” 循环结构,其一般形式为 “while (表达式) 语句;”,当表达式的值非 0 时,执行 while 语句中的内嵌语句。其特点是:先判断表达式,后执行语句。
int main(){
int i =1;
int total = 0;
while(i<=100){
total = total +i;
i++;
}
printf("total=%d\n",total);
}
2
3
4
5
6
7
8
9
# do while 循环
do while 语句的特点是:先执行循环体,后判断循环条件是否成立。其一般形式为
do
{
循环体语句;
}
while (表达式);
2
3
4
5
执行过程如下:首先执行一次指定的循环体语句,然后判断表达式,当表达式的值为非零(真) 时,返回重新执行循环体语句,如此反复,直到表达式的值等于 0 为止。
int main(){
int i =1;
int total = 0;
do{
total = total +i;
i++;
}while(i<=100);
printf("total=%d\n",total);
}
2
3
4
5
6
7
8
9
# for 循环
C 语言中的 for 循环语句使用最为灵活,不仅可以用于循环次数已经确定的情况,而且可以用于循环次数不确定而只给出循环结束条件的情况,它完全可以代替 while 循环语句。其一般形 式为
for(表达式 1;表达式 2;表达式 3) 语句;
for 循环语句的执行过程如下,具体流程如图 3.2.7 所示。
- 先求解表达式 1。
- 求解表达式 2,若其值为真(值为非 0),则先执行 for 语句中指定的内嵌语句,后执行 第(3)步。若其值为假(值为 0),则结束循环,转到第(5)步。
- 求解表达式 3。
- 转回第(2)步继续执行。
- 循环结束,执行 for 语句下面的语句。

int main() {
int i, total;
for (i = 1, total = 0; i <= 100; i++) {
total = total + i;
}
printf("total=%d\n", total);
}
2
3
4
5
6
7
# continue 语句
continue 语句的作用为结束本次循环,即跳过循环体中下面尚未执行的语句,接着进行是否执行下一次循环的判断。其一般形式为
continue;
下面来看一个对 1 到 100 之间的奇数进行求和的例子,当 continue 用于 while 和 do while 循环中时,注意不要跳过让循环趋近于假的语句。
int main() {
int i, total;
for (i = 1, total = 0; i <= 100; i++) {
if(i%2==0){
continue;
}
total = total + i;
}
printf("total=%d\n", total);
}
2
3
4
5
6
7
8
9
10
# break 语句
break 语句的作用是结束整个循环过程,不再判断执行循环的条件是否成立。Break 语句也可用在 while 循环和 do while 循环中, 起结束对应循环的作用。
int main() {
int i, total;
for (i = 1, total = 0; i <= 100; i++) {
if(total > 2000){
break;
}
total = total + i;
}
printf("total=%d\n", total);
}
2
3
4
5
6
7
8
9
10