流程控制

分支语句 - if

我们可能会有这样的一个需求,就是判断某个条件,当满足此条件时,才执行某些代码,那这个时候该怎么办呢?我们可以使用if语句来实现:

#include <stdio.h>

int main() {
    int i = 0;
    if(i > 20) {    //我们只希望i大于20的时候才执行下面的打印语句
        printf("Hello World!");
    }
  	printf("Hello World?");   //后面的代码在if之外,无论是否满足if条件,都跟后面的代码无关,所以这里的代码任何情况下都会执行
}

if语句的标准格式如下:

if(判断条件) {
    执行的代码
}

当然如果只需要执行一行代码的话,可以省略花括号:

if(判断条件)
  一行执行的代码   //注意这样只有后一行代码生效,其他的算作if之外的代码了

现在我们需求升级了,我们需要判断某个条件,当满足此条件时,执行某些代码,而不满足时,我们想要执行另一段代码,我们就可以结合else语句来实现:

#include <stdio.h>

int main() {
    int i = 0;
    if(i > 20) {
        printf("Hello World!");   //满足if条件才执行
    } else {
        printf("LBWNB");   //不满足if条件才执行
    }
}

但是这样可能还是不够用,比如我们现在希望判断学生的成绩,不同分数段打印的等级不一样,比如90以上就是优秀,70以上就是良好,60以上是及格,其他的都是不及格,那么这种我们又该如何判断呢?要像这样进行连续判断,我们需要使用else-if来完成:

#include <stdio.h>

int main() {
    int score =  2;
    if(score >= 90) {
        printf("优秀");
    } else if (score >= 70) {
        printf("良好");
    } else if (score >= 60){
        printf("及格");
    } else{
        printf("不及格");
    }
}

if这类的语句(包括我们下面还要介绍的三种)都是支持嵌套使用的,比如我们现在希望低于60分的同学需要补习,0-30分需要补Java,30-60分需要补C++,这时我们就需要用到嵌套:

#include <stdio.h>

int main() {
    int score =  2;
    if(score < 60) {   //先判断不及格
        if(score > 30) {   //在内层再嵌套一个if语句进行进一步的判断
            printf("学习C++");
        } else{
            printf("学习Java");
        }
    }
}

分支语句 - switch

前面我们介绍了if语句,我们可以通过一个if语句轻松地进行条件判断,然后根据对应的条件,来执行不同的逻辑,当然除了这种方式之外,我们也可以使用switch语句来实现,它更适用于多分支的情况:

switch (目标) {   //我们需要传入一个目标,比如变量,或是计算表达式等
  case 匹配值:    //如果目标的值等于我们这里给定的匹配值,那么就执行case后面的代码
    代码...
    break;    //代码执行结束后需要使用break来结束,否则会继续溜到下一个case继续执行代码
}

比如现在我们要根据学生的等级进行分班,学生有ABC三个等级:

#include <stdio.h>

int main() {
    char c = 'A';
    switch (c) {  //这里目标就是变量c
        case 'A':    //分别指定ABC三个匹配值,并且执行不同的代码
            printf("去尖子班!准备冲刺985大学!");
            break;   //执行完之后一定记得break,否则会继续向下执行下一个case中的代码
        case 'B':
            printf("去平行班!准备冲刺一本!");
            break;
        case 'C':
            printf("去职高深造。");
            break;
    }
}

switch可以精准匹配某个值,但是它不能进行范围判断,比如我们要判断分数段,这时用switch就很鸡肋了。

当然除了精准匹配之外,其他的情况我们可以用default来表示:

switch (目标) {
    case: ...
    default:
    		其他情况下执行的代码
}

比如:

#include <stdio.h>

int main() {
    char c = 'A';
    switch (c) {
        case 'A':
            printf("去尖子班!");
            break;
        case 'B':
            printf("去平行班!");
            break;
        case 'C':
            printf("去差生班!");
            break;
        default:   //其他情况一律就是下面的代码了
            printf("去读职高,分流");
    }
}

当然switch中可以继续嵌套其他的流程控制语句,比如if:

#include <stdio.h>

int main() {
    char c = 'A';
    switch (c) {
        case 'A':
            if(c == 'A') {    //嵌套一个if语句
                printf("去尖子班!");   
            }
            break;
        case 'B':
            printf("去平行班!");
            break;
    }
}

循环语句 - for

通过前面的学习,我们了解了如何使用分支语句来根据不同的条件执行不同的代码,我们接着来看第二种重要的流程控制语句,循环语句。

我们在某些时候,可能需要批量执行某些代码:

#include <stdio.h>

int main() {
    printf("伞兵一号卢本伟准备就绪!");   //把这句话给我打印三遍
    printf("伞兵一号卢本伟准备就绪!");
    printf("伞兵一号卢本伟准备就绪!");
}

遇到这种情况,我们由于还没学习循环语句,那么就只能写N次来实现这样的多次执行。现在我们可以使用for循环语句来多次执行:

for (表达式1表达式2;表达式3) {
    循环体
}

我们来介绍一下:

  • 表达式1:在循环开始时仅执行一次。
  • 表达式2:每次循环开始前会执行一次,要求为判断语句,用于判断是否可以结束循环,若结果为真,那么继续循环,否则结束循环。
  • 表达式3:每次循环完成后会执行一次。
  • 循环体:每次循环都会执行循环体里面的内容,直到循环结束。

一个标准的for循环语句写法如下:

//比如现在我们希望循环4次
for (int i = 0; i < 4; ++i) {
    //首先定义一个变量i用于控制循环结束
  	//表达式2在循环开始之前判断是否小于4
  	//表达式3每次循环结束都让i自增一次,这样当自增4次之后不再满足条件,循环就会结束,正好4次循环
}

我们来看看按顺序打印的结果:

#include <stdio.h>

int main() {
    //比如现在我们希望循环4次
    for (int i = 0; i < 4; ++i) {
        printf("%d, ", i);
    }
}

流程控制_c

这样,利用循环我们就可以批量执行各种操作了。

注意,如果表达式2我们什么都不写,那么会默认判定为真:

#include <stdio.h>

int main() {
    for (int i = 0; ; ++i) {   //表达式2不编写任何内容,默认为真,这样的话循环永远都不会结束
        printf("%d, ", i);
    }
}

流程控制_c_02

所以,如果我们想要编写一个无限循环,其实什么都不用写就行了:

#include <stdio.h>

int main() {
    for (;;) {   //什么都不写直接无限循环,但是注意,两个分号还是要写的
        printf("Hello World!\n");   //这里用到了\n表示换行
    }
}

当然,我们也可以在循环过程中提前终止或是加速循环的进行,这里我们需要认识两个新的关键字:

for (int i = 0; i < 10; ++i) {
    if(i == 5) break;   //比如现在我们希望在满足某个条件下提前终止循环,可以使用break关键字来跳出循环
    printf("%d", i);
}

流程控制_c_03

可以看到,当满足条件时,会直接通过break跳出循环,循环不再继续下去,直接结束掉。

我们也可以加速循环:

for (int i = 0; i < 10; ++i) {
    if(i == 5) continue;   //使用continue关键字会加速循环,无论后面有没有未执行完的代码,都会直接开启下一轮循环
    printf("%d", i);
}

流程控制_c_04

虽然使用break和continue关键字能够更方便的控制循环,但是注意在多重循环嵌套下,它只对离它最近的循环生效(就近原则):

for (int i = 1; i < 4; ++i) {
    for (int j = 1; j < 4; ++j) {
        if(i == j) continue;    //当i == j时加速循环
        printf("%d, %d\n", i, j);
    }
}

流程控制_c_05

可以看到,continue仅仅加速的是内层循环,而对外层循环没有任何效果,同样的,break也只会终结离它最近的:

for (int i = 1; i < 4; ++i) {
    for (int j = 1; j < 4; ++j) {
        if(i == j) break;    //当i == j时终止循环
        printf("%d, %d\n", i, j);
    }
}

流程控制_c_06

循环语句 - while

前面我们介绍了for循环语句,我们接着来看第二种while循环,for循环要求我们填写三个表达式,而while相当于是一个简化版本,它只需要我们填写循环的维持条件即可,比如:

#include <stdio.h>

int main() {
    while (1) {   //每次循环开始之前都会判断括号内的内容是否为真,如果是就继续循环
        printf("Hello World!\n");   //这里会无限循环
    }
}

相比for循环,while循环更多的用在不明确具体的结束时机的情况下,而for循环更多用于明确知道循环的情况,比如我们现在明确要进行循环10次,此时用for循环会更加合适一些,又比如我们现在只知道当i大于10时需要结束循环,但是i在循环多少次之后才不满足循环条件我们并不知道,此时使用while就比较合适了。

#include <stdio.h>

int main() {
    int i = 100;   //比如现在我们想看看i不断除以2得到的结果会是什么,但是循环次数我们并不明确
    while (i > 0) {   //现在唯一知道的是循环条件,只要大于0那么就可以继续除
        printf("%d, ", i);
        i /= 2;   //每次循环都除以2
    }
}

流程控制_c_07

while也支持使用break和continue来进行循环的控制:

int i = 100;
while (i > 0) {
    if(i < 30) break;
    printf("%d, ", i);
    i /= 2;
}

流程控制_c_08

我们可以反转循环判断的位置,可以先执行循环内容,然后再做循环条件判断,这里要用到do-while语句:

#include <stdio.h>

int main() {
    do {  //无论满不满足循环条件,先执行循环体里面的内容
        printf("Hello World!");
    } while (0);   //再做判断,如果判断成功,开启下一轮循环,否则结束
}

流程控制_c_09

实战:打印九九乘法表

流程控制_c_10

流程控制_c_11