07. 流程控制

一、流程控制

  流程控制就是用来控制程序运行中各语句执行顺序的语句。基本的流程结构为:顺序结构分支结构(或称选择结构),循环结构

  • 顺序结构:程序自上到下执行,中间没有任何判断和跳转;
  • 分支结构:根据条件,选择性的执行某段代码,有 if……elseswitch……case 两种分支语句;
  • 循环结构:根据循环条件,重复性的执行某段代码,有 whiledo……whilefor 三种循环语句;

二、顺序结构

  顺序结构 是 C语言 程序默认的执行流程,按照代码的先后顺序,从上到下依次执行,中间没有任何的判断和跳转

顺序结构执行流程

#include <stdio.h>

int main(void)
{
    printf("你好,世界!\n");
    printf("Hello world!\n");

    return 0;
}

三、分支结构

  选择语句 也被称为 分支语句,它通过给定的条件进行判断,从而决定执行两个或者多个分支中哪一只。因此,在编写选择语句之前,应该首先明确判断条件是什么,并确定判断结果为“真”或“假”时应分别执行什么样的操作/算法。在 C 语言中选择语句主要提供了两种,一个是 if 语句,另一个则是 switch 语句

3.1、if语句

3.1.1、if语句的单分支结构

if(关系表达式)
{
    语句体;
}

  执行流程

  1. 首先计算 关系表达式 的值
  2. 如果关系表达式的值为 真(非 0)执行语句体
  3. 如果关系表达式的值为 假(0)不执行语句体
  4. 继续执行后面的其它语句

if语句的单分支结构执行流程

#include <stdio.h>

int main(void)
{
    int number;

    printf("请输入一个数:");
    scanf("%d",&number);

    if (number > 10)
        printf("你输入的数字比10大\n");
  
    printf("你输入的数字是:%d\n",number);

    return 0;
}

在语句体中,如果只有一句代码,大括号可以省略不写,建议不要省略;

if 结构是可以嵌套的;

3.1.2、if语句的双分支结构

if(关系表达式)
{
    语句体1;
} 
else 
{
    语句体2;
}

  执行流程

  1. 首先计算 关系表达式 的值
  2. 如果关系表达式的值为 真(非 0) 就执行 语句体 1
  3. 如果关系表达式的值为 假(0) 就执行 语句体 2
  4. 继续执行后面的其它语句

if语句的双分支结构执行流程

#include <stdio.h>

int main(void)
{
    int number;

    printf("请输入一个数:");
    scanf("%d",&number);

    if (number > 10)
        printf("你输入的数字比10大\n");
    else
        printf("你输入的数字等于10或者比10小\n");
  
    printf("你输入的数字是:%d\n",number);

    return 0;
}

当使用 if 语句的双分支结构进行嵌套使用时,如果没有花括号,else 默认与最近的未匹配的 if 语句配对,除非最近的 if 被花括号括起来;

3.1.3、if语句的多分支结构

if(关系表达式1)
{
    语句体1;
} 
else if (关系表达式2)
{
    语句体2;
} 
……
else 
{
    语句体n+1;
}

  执行流程

  1. 首先计算 关系表达式 1 的值
  2. 如果为 真(非 0) 就执行 语句体 1;如果为 假(0) 就计算 关系表达式 2 的值
  3. 如果为 真(非 0) 就执行 语句体 2;如果为 假(0) 就计算 关系表达式 3 的值
  4. ……
  5. 如果 所有的关系表达式 结果都为 假(0),就执行 else 子句中的 语句体 n+1
  6. 继续执行其它语句

if语句的多分支结构执行流程

#include <stdio.h>

int main(void)
{
    int number;

    printf("请输入一个数:");
    scanf("%d",&number);

    if (number > 10)
        printf("你输入的数字比10大\n");
    else if(number < 10)
        printf("你输入的数字比10小\n");
    else
        printf("你输入的数为10\n");
  
    printf("你输入的数字是:%d\n",number);

    return 0;
}

else 结构是可选的;

if-else if-else 结构中最多只会有一个语句体执行;

如果多个条件表达式之间是 “互斥” 关系,哪个判断和执行语句声明在上面还是下面,无所谓;

如果多个条件表达式之间有 “交集” 关系,需根据实际情况,考虑清除应该将哪个结构写在上面;

如果多个条件表达式之间有 “包含” 关系,通常情况下,需要 将范围小的声明在范围大的上面。否则,范围小的没机会执行;

3.2、switch语句

switch(整型表达式)
{
    case 整型常量表达式1:
        语句体1;
        break;
    case 整型常量表达式2:
        语句体2;
        break;   
    ……
    case 整型常量表达式n:
        语句体n;
        break;  
    default:
        语句体n+1;
        break;
}

  执行流程

  1. 首先计算 表达式 的值
  2. 依次和 case 后面的值 进行比较,如果 有对应的值,就会执行相应的语句, 在执行过程中,遇到 break 就会结束
  3. 如果 所有的 case 后面的值 和 表达式 的值都不匹配,就会执行 default 里面的语句体,然后结束整个 switch 语句

  格式说明

  • 表达式:表达式的结果是 整型变量
  • case:后面跟的是 要和 switch 中的表达式进行比较的常量表达式,它只能是 枚举常量数值常量字符常量常变量宏定义常量 的一种,且 case 给出的值不能重复
  • break:表示中断,结束的意思,用来 结束 switch 语句,break 关键字是可选的
  • default:表示 所有情况都不匹配的时候,就执行该处的内容,相当于 if……else 中的 else,default 结构是可选的,而且位置是灵活的;

  如果在语句体中 没有写 break 关键字,可能会导致 case穿透现象case穿透现象 的执行流程如下:首先还是会拿着小括号中表达式的值跟下面的每一个 case 进行匹配,如果匹配上了,就会执行相应的代码,如果此时发现了 break,那么结束整个 switch 语句。如果没有发现 break,那么程序会继续执行下一个 case 语句体,一直遇到 break 或者 右大括号为止;

switch结构执行流程

#include <stdio.h>

int main(void)
{
    int day;

    printf("请输入一个星期数:");
    scanf("%d",&day);

    switch(day)
    {
        case 1:
            printf("你输入的是星期一\n");
            break;
        case 2:
            printf("你输入的是星期二\n");
            break;
        case 3:
            printf("你输入的是星期三\n");
            break;
        case 4:
            printf("你输入的是星期四\n");
            break;
        case 5:
            printf("你输入的是星期五\n");
            break;
        case 6:
            printf("你输入的是星期六\n");
            break;
        case 7:
            printf("你输入的是星期天\n");
            break;
        default:
            printf("你输入的星期数不对\n");
            break;
    }

    return 0;
}

凡是可以使用 switch……case 的结构,都可以转换为 if……else 。反之,不成立;

分支结构,既可以使用 switch……case(同时,switch 中表达式的取值不多时)又可以使用 if……else 时,优先使用 switch……case;

四、循环结构

  循环就是重复的做某件事情;它具有明确的开始和停止标志;一组被重复执行的语句称之为 循环体,能否继续执行,取决于 循环的终止条件。在 C 语言中循环分为 for循环while循环do..while循环;循环结构具有以下四个组成部分:

  1. 初始化部分(init_statement)
  2. 循环条件部分(test_exp)
  3. 循环体部分(body_statement)
  4. 迭代部分(alter_statement)

  通常情况下,循环结构都是因为 ② 中循环条件返回 false;

4.1、for循环

for(①初始化条件;②循环条件;④迭代条件)
{
    ③循环体;
}

  执行流程

  1. 执行 初始化语句
  2. 执行 条件判断语句,看其结果是 真(非 0) 还是 假(0)
    • 如果是 假(0)循环结束,继续执行后面的其它语句
    • 如果是 真(非0)执行循环体语句
  3. 执行 条件控制语句
  4. 回到②继续执行 条件判断语句

for循环与while循环结构执行流程

#include <stdio.h>

int main(void)
{
    int i;

    for (i = 0; i < 10; i++)
    {
        printf("Hello world!\n");
    }

    return 0;
}

初始化语句作为循环的开始,只会执行一次

如果判断条件为 真(非 0),则循环继续;如果判断语句为 假(0),则循环结束;

for 循环 中可以添加多个初始化条件、条件判断内容、条件控制语句,多条内容之间中间用逗号分隔;

4.2、while循环

①初始化条件;
while(②循环条件)
{
    ③循环体;
    ④迭代条件;
}

  执行流程

  1. 执行 初始化语句
  2. 执行 条件判断语句,看其结果是 真(非 0) 还是 假(0)
    • 如果是 假(0)循环结束,继续执行后面的其它语句
    • 如果是 真(非 0)执行循环体语句
  3. 执行 条件控制语句
  4. 回到 ② 继续执行 条件判断语句

for循环与while循环结构执行流程

#include <stdio.h>

int main(void)
{
    int i;

    while(i < 10)
    {
        printf("Hello world!\n");
        i++;
    }

    return 0;
}

如果判断条件为 true,则循环继续;如果判断语句为 false,则循环结束;

for 循环和 while 循环可以相互转换的;

4.3、do...while循环

①初始化条件
do{
    ③循环体;
    ④迭代条件;
}while(②循环条件);

  执行流程

  1. 执行 初始化语句
  2. 执行 循环体语句
  3. 执行 条件控制语句
  4. 执行 条件判断语句,看其结果是 真(非 0) 还是 假(0)
    • 如果是 假(0)循环结束,继续执行后面的其它语句
    • 如果是 真(非0)执行循环体语句
  5. 执行 条件控制语句
  6. 回到 ② 继续执行 条件判断语句

do...while循环结构执行流程

#include <stdio.h>

int main(void)
{
    int i;

  
    do{
        printf("Hello world!\n");
        i++;
    }while(i < 10);

    return 0;
}

do...while 循环先执行后判断,即循环体至少执行一次;

4.4、无限循环

  for 循环的无限循环:

for(;;)
{
    循环体;
}

  while 循环的无限循环:

while(1)
{
    循环体;
}

  do...while 循环的无限循环

do{
    循环体;
} while(1);

4.5、嵌套循环

  将一个循环结构 A 声明在另一个循环结构 B 的循环体,就构成了嵌套循环;

  • 外层循环:循环结构 B,控制行数
  • 内层循环:循环结构 A,控制列数

  内层结构遍历一遍,相当于外层循环循环体执行一次;假设外层循环需要执行 m 次,内层循环需要执行 n 次。此时内层循环的循环体一共执行了 m*n 次;

#include <stdio.h>

int main(void)
{
    int i,j;

  
    for (i = 1; i <= 9; i++) 
    {
        for (j = 1; j <= i; j++) 
        {
            printf("%d * %d = %-5d",i,j,i*j);
        }
        printf("\n");
    }

    return 0;
}

五、跳转语句

5.1、break与continue的使用

  break 的作用是 结束当前循环,后面不能直接写执行语句,默认跳出包裹此关键字最近的一层循环;执行完 break 语句后会直接执行循环后面的第 1 条语句,连更新部分也跳过。嵌套循环内层的 break 只会让程序跳出包含它的当前循环,要跳出外层循环还需要一个 break。

#include <stdio.h>

int main(void)
{
    int i;

    for (i = 0; i <= 5; i++) 
    {
        if (i == 3)
            break;
  
        printf("%d\n",i);
    }

    return 0;
}

  continue 的作用是 结束当次循环,后面不能直接写执行语句,默认结束包裹此关键字最近的循环的一次;对于 while 循环 和 do…while 循环,执行 continue 语句后的下一个行为是对循环的测试表达式求值;对于 for 循环,执行 continue 后的下一个行为是对更新表达式求值,然后是对循环测试表达式求值,

#include <stdio.h>

int main(void)
{
    int i;

    for (i = 0; i <= 5; i++) 
    {
        if (i == 3)  
            continue;
  
        printf("%d\n",i);
    }

    return 0;
}
#include <stdio.h>

int main(void)
{
    int i = 0;

    while(i < 10) 
    {
        i++;
        if (i == 3)
            continue;
  
        printf("%d\n",i);
    }

    return 0;
}

continue 语句只能配合循环语句使用,不能单独和 switch/if 使用;

break 除了可以用在循环中,还可以和 swtich 语句搭配使用;

5.2、goto语句

  C 语言的 goto 语句可以无条件转移到程序中指定的行,goto 语句通常与条件语句配合使用,可用来实现条件转移,跳出循环体等功能。在 C 程序中,一般不主张使用 goto 语句,以免造成程序流程的混乱,使理解和调试程序都产生困难。它的格式如下:

goto 标签;
标签:语句;
标签:语句;
goto 标签;

  其中,标签是一个有效的标识符。这个标识符加上一个 “:” 一起出现在函数内某处,执行 goto 语句后,程序将跳转到该标识符处并执行其后的语句。另外,标签需要与 goto 语句处于同一个函数中。

#include <stdio.h>

int main(void)
{
    // FLAG是一个标识符
    goto FLAG;
    printf("hello world!\n");
    FLAG:
    printf("你好,世界!\n");

    return 0;
}
#include <stdio.h>

int main(void)
{
    int i = 0,j = 0;

    for(i = 0; i < 10; i++){
        if(i == 5){ goto FLAG; }
        printf("i = %d\n",i);
    }

    for(j = 0; j < 10; j++){
        FLAG:
        printf("j = %d\n",j);
    }
  
    return 0;
}
#include <stdio.h>

int main(void)
{
    // 相当于死循环
    FLAG:
        printf("hello world!\n");
    goto FLAG;

    return 0;
}
posted @ 2023-02-25 12:19  星光樱梦  阅读(36)  评论(0编辑  收藏  举报