Skip to content

第三部分:流程控制


一、选择结构

1.if…else 选择结构

在高中数学中,我们学过这样的程序结构:

alt text

图:选择结构流程图

这个流程图的程序运行过程是:当表达式为真,则沿着左侧的箭头向下执行,否则沿着右侧的箭头向下执行。例如:

c
#include<stdio.h>		
int main()
{
    int a;
    printf("请输入你的性别,1为男,2为女:\n");
    scanf("%d",&a);
    if(a = 1)
    {
        printf("你是男生\n");
    }
    if(a = 2)
    {
        printf("你是女生\n");
    }
    else
    {
        printf("你确定没有输入错?\n");
    }
    return 0;
}

上述程序运行时,先提示用户输入数字,然后按照要求输出男或女。这是一个选择结构的典例。选择结构的一般形式如下:

if(表达式 1)
    语句 1;
if(表达式 2)
    语句 2;
if(表达式 3)
    语句 3;

if(表达式 n)
    语句 n;
else
    语句 n + 1;

需要注意的是,表达式 1 ~ 表达式 n 都是逻辑表达式,即能判断正误的表达式。当表达式的值为1TRUE)则执行此 if 下的语句,否则继续执行下一个 if 的判断。当语句 1 ~ 语句 n 为多条语句时,则要用花括号将其括在一起变成语句体。

2.switch 多分支选择结构

switch-case-default 结构可以实现多分支选择。例如要编写一个程序,根据学生的成绩等级来输出成绩区间:

c
int main()
{
	char grade;
    printf("输入你的成绩等级:\n");
    scanf("%c", &grade);
    switch(grade)
    {
        case 'A' : printf("80~100\n"); break;
        case 'B' : printf("60~80\n"); break;
        case 'C' : printf("40~60\n"); break;
        case 'D' : printf("0~40\n"); break;
        default : printf("输入错误");
    }
    return 0;
}

当程序遇到 switch 关键字时,会将括号中的变量与 switch 语句体中的每个 case 匹配,执行对应的语句。每个 case 语句后都有一个 break,它的作用是跳出这个 case 转到 switch 语句体结束。如果没有 break 的话,会在匹配到的 case 依次向下执行。

3.选择结构的嵌套

ifswitch 两种选择结构可以互相嵌套,形成嵌套结构。例如:

c
#include<stdio.h>
int main()
{
    int x, y;
    scanf("%d", &x);
    if(x < 0)
        y = -1
    else
        if(x == 0)
            y = 0;
        else
            y = 1;
    printf("x = %d, y = %d\n", x, y);
    return 0;
}

如上程序的流程如下图:

alt text

图:if 的选择结构嵌套示意图

这个程序体现了 if 语句的嵌套结构。当我们在设计程序算法,遇到分支的情况时,需要合理设计选择结构的嵌套。这将会在日后的编程中渐渐体会到。

4.改变选择结构的状态 break

switch 选择结构中,如果在每一个分支后面没有特定的说明,默认会在此分支执行结束之后跳转到下一个分支。例如在第三部分、一、2 的 switch 例程中,如果输入 A,且每一个 case 语句结束的位置都没有 break 的话,输出结果是:

sh
80~100
60~80
40~60
0~40
输入错误

进行算法设计时,要根据具体需要来使用 break 来改变程序运行状态,来使算法适合要解决的问题。

二、循环结构

首先要讲到为什么要使用循环结构。例如当我们需要求 1 ~ 100 自然数之和,这个时候是不能用常规方法手工输入 1 ~ 100 个整数然后让计算机去进行计算的。如果那样的话,有 1000 或者更多的数字需要计算时怎么办?这个时候就需要用到循环结构。例如上面的问题有这样的解决方法:

c
#include<stdio.h>
int main()
{
    int i, s;
    s = 0;
    for(i = 1; i <= 100; i ++)
    {
        s = s + i;
    }
    printf("%d", s);
    return 0;
}

这个程序的运行结果是:

sh
5050

常用的循环结构有:forwhiledo…while 三种,三种循环结构的功能相同,但各有各的特点,所以它们各自能实现不同的功能。同时它们各自可以互相嵌套,还可以改变循环的状态,所以,善用循环结构往往能减少巨大的工作量,让电脑代替人脑完成一些人脑无法完成的工作。

1.whiledo…while 循环结构

while 结构的一般形式是:

while(表达式) 
    语句;

这个结构的运行过程是,首先判断表达式的真假,如果为真,则执行语句。语句可以为语句体,此时需要用花括号将语句体括起来。在 while 后面执行的语句(体)称为循环体。

do…while 结构的一般形式是:

do
    语句;
while(表达式)

这个程序的运行过程是,首先执行语句(体),再判断表达式真假,如果表达式为真,再进行循环。

2.for 循环结构

除了上述的两种循环结构外,C 语言还提供了另外一种更加灵活的 for 循环结构。它完全可以代替 whiledo…while 语句。for 语句的一般形式是:

for(表达式1 ; 表达式2 ; 表达式3)
    语句;

三个表达式的作用都不相同。表达式1设置初始条件,执行一次,可以没有、一个、或者多个;表达式 2 为判断是否执行循环的条件,当表达式2的值为真时,执行循环体;表达式 3 为循环的变化量,可以没有、一个或多个,执行一次。所以 for 语句的一般形式可以理解为:

for(赋初值 ; 循环条件 ; 增量)
    语句;

for 语句的一种极端形式是:

for( ; ; )

这句语句与

while(1)

是等价的,代表无条件循环。

for 循环体的执行过程是,先执行表达式 1,然后判断表达式 2 的真假,如果为真,执行语句,语句可以为语句体。语句(体)执行过后,执行表达式 3,for 的循环体到此执行完一次循环。整个过程如下图:

alt text

图:for 循环结构示意图

可以将 for 循环结构改写为 while 循环结构:

表达式 1;
while (表达式 2)
{
    语句;
    表达式 3;
}

上述结构与 for 一般形式的循环结构完全等价。基于这种原理,我们可以将之前提到的求 1 ~ 100 自然数和的程序改写:

c
int i, s = 0;
while(i <= 100)
{
    s = s + i;
    i ++;
}
c
int i, s = 0;
do
{
    s = s + i;
    i ++;
}
while(i <= 100)

3.循环结构的嵌套

上述三种循环结构的优缺点各不相同,在解决程序设计问题时各自能解决不同特征的问题。三种结构可以互相嵌套,实现更强大的功能。当进行设计比较复杂的循环问题时,应该注意代码的规范性,即每层嵌套之间有一个 Tab 键的缩进,这样的话代码看上去有层次感,一眼望去能看出都哪几行代码属于一个层次。便于别人阅读也便于自己修改。

具体的循环嵌套问题还要在日后解决问题中慢慢理解。

4.改变循环结构的状态

当我们解决问题时,往往会遇到需要提前终止循环的情况。例如我们想要求1~一个很大的自然数中所有质数的和,这样我们设置一个1~很大的数的循环,每次遇到质数就把这个数加在和变量中,判断不是质数的话就跳过本次循环。这种方式叫做改变循环的状态。

在 C 语言中,有两种改变循环状态的方式:breakcontinue。为了讲解这两种方式,我们分别举不同的例子。

例如,我们在全校 1000 名同学范围内筹集资金,当资金数累计到十万元的时候就停止筹集。统计此时捐款人数。我们可以这样编写程序:

c
#include<stdio.h>
int main()
{
    float num, sum = 0;
    int i;
    for(i = 0 ; i < 1000 ; i ++)
    {
        printf("输入捐款金额:");
        scanf("%f" , &num);
        printf("\n");
        sum = sum + num;
        if(sum >= 100000)
            break;
    }
    printf("有%d人参加捐款。\n", i);
    return 0;
}

在程序中可以看出,在第 13 行程序判断 sum >= 100000 是否成立,成立的话程序遇到 break,跳出整个循环。再看下面的例子。输出 1~100 之间可以被 3 整除的数,程序如下:

c
#include<stdio.h>
int main()
{
    int i;
    for(i = 0; i <= 100; i ++)
    {
        if(i % 3 != 0)
           continue;
        printf("%d\t", i);
    }
    printf("输出完毕!\n");
    return 0;
}

在程序中可以看出,当程序遇到 continue 时,跳过本次循环,但循环还在继续。这时候需要自己体会二者的差别。

三、练习题

  1. 输出 1 ~ 1000 整数范围内所有的“水仙花数”。“水仙花数”即其各位数字的立方和等于其本身。例如 153 = 1 ^ 3 + 5 ^ 3 + 3 ^ 3 = 153,153 为一个水仙花数。

  2. 1! + 2! + 3! + … + 20! 的值。

  3. 输出以下图形:

   *   
  ***  
 ***** 
*******
 ***** 
  ***  
   *

© thebestxt.cc
辽ICP备16009524号-8
本站所有文章版权所有,转载请注明出处