Skip to content
On this page

流程控制

所谓流程控制,就是控制计算机在什么条件下执行哪条语句

一般来说可以分为3种控制流,分别是顺序结构,分支结构和循环结构

通过不同控制流的组合以及嵌套可以实现非常复杂的功能

顺序结构

指的是程序的语句按序执行,自上而下。这是最简单的结构

Cpp
#include <iostream>

int main() {
    int a = 1;   // 1
    int b = 2;   // 2 
    std::cout << "a + b = " <<  a + b << std::endl; // 3 
}

在如上的程序中,程序会依次执行 1 2 3 号语句

分支结构

如果我们希望在某种条件下,只执行一段代码而不执行另一段代码,那么分支结构可以帮助到我们

在 C++ 中有两种分支结构, 一种是 if-else 另一种是 switch case

if-else 结构

通常 if-else 结构的语法是

Cpp
if ( 情况 ) {
   // 当情况为真时执行
}
else {
	// 当情况不为真时执行
}

这表示当 情况 为真时,执行第一个花括号的内容,当情况不为真时,执行第二个花括号的内容

其中情况是c++中的一个布尔类型的有效表达式

所谓有效表达式,就是可以放在等于号=后边的语句

如以下等号后面的部分就是有效表达式

Cpp
int a = 1;
int b = 2
bool c = true
bool d = a > b;
bool e = a < b || a == b

如下是一个完整的程序示例

Cpp
#include <iostream>

int main() {
    int a = 1;  
    int b = 2;

    if (a > b) {
        std::cout << "a更大" <<  std::endl; 
    } else {
        std::cout << "b更大" <<  std::endl; 
    }
}

程序会输出 b更大

当然 if-else 结构也可以不写 else,此时就表示如果条件满足则执行 if 块,如果不满足则继续向下执行,比如下面的示例

cpp
#include <iostream>

int main {
	int a = 1;
	int b = 2;

	if(a == b) {
		std::cout << "a和b相等" << endl;
	}

	std::cout << "这段话依然会执行" << endl;
}

运行之后会有如下结果

txt
这段话依然会执行

if-else-if 结构

if-else-if 结构是 if-else 的拓展,当第一个条件不满足时,才会检查第二个条件是否满足,如果满足,则执行第二个分支的代码,否则执行 else 代码块。需要注意的是,这种结构可以多次使用,以达到多分支的效果

以下是 if-else-if 块的一般结构

Cpp
if (情况1) {
	// 块1 
}
else if (情况2) {
	// 块2
} else {
	// 块3
}

情况1 满足时,不管 情况2 满足与否都执行 块1 当 情况1 不满足且 情况2 满足时,执行 块2 当 情况1情况2都不 满足时,执行 块3

switch-case 结构

有时候我们会碰到这样一种情况:要根据一个变量的不同取值而采取不同的动作,如果采用 if-else-if 结构,则以下代码可以完成需求

Cpp
int a = 1;

if (a == 1) {
	//当 a = 1 执行
} 
else if (a == 2) {
	//当 a = 2 执行
} else if (a == 3) {
	//当 a = 3 执行
} else {
	//当上面所有条件都不符合时执行
}

然而 C++ 提供了更好的语法支持, 即 switch-case 结构,其一般格式如下

Cpp
int a = 1;

switch(a) {
	case 1:
		//当 a = 1 执行
	break;

	case 2:
		//当 a = 2 执行
	break;

	case 3:
		//当 a = 3 执行
	break;

	default:
		//当上面所有条件都不符合时执行
	break;
}

以上代码段和上一个代码段实现了完全一样的功能:根据变量 a 的取值而采取不同的行动,当 a 的值都不满足给出的值时,就会执行default/else 的代码

WARNING

break是不建议省略的,如果不写可以成功通过编译,因为这在语法上并不存在问题,但是会出现语义错误:当执行到中间的 case 时,如果匹配成功,不仅仅会执行此处case下的逻辑,还会z执行后续其他 case 情况下的代码块,直到出现一个break,或者全部执行完毕。

在实际开发的时候应该尽量避免不写 break,除非你知道自己在干什么。另外有些无聊的学校会把没有breakcase当作一个特殊考点

循环结构

指的是根据某些条件重复执行一段语句的结构,当我们期待某段代码重复执行或者多次执行但是每次产生一些变化的时候,可以使用循环结构。循环结构有两大类型 分别是 forwhile 语句

for 循环

for 语句主要应用在有数字连续变化的场景,格式如下:

Cpp
for(初始化代码; 情况; 下一步) {
	// 运行代码
}

各段说明如下

初始化代码:在循环开始前执行一次,一般用于定义变量和初始化变量,定义的变量可以在 for 块中使用,并且定义域只存在于这个for循环

情况: 每次循环前都会判断条件是否仍然成立,如果不成立则停止循环

下一步:每次循环后都会雷打不动执行,一般用于改变循环前面 初始化 中定义的变量的值

以下实例展示了 for 结构的简单使用

Cpp
#include<iostream>

int main() {
	for(int i = 0; i < 10; i++) {
		std::cout << i << std::flush;
	}
}

程序会输出

txt
0123456789

TIP

这段代码里面我们接触了std::flush,这是一个输出流控制符,用于将缓冲区的字符直接打印到输出目标上,在此处我们仅作了解即可

while 和 do while 循环

for 不同的是,while 每次循环前只检查条件是否满足,满足则继续,不满足就结束循环;do while 则不管满足与否,会先执行一次循环体,再判断条件是否满足

以下是使用 while 循环的一个简单的实例

Cpp
#include<iostream>

int main() {
	int i = 5;

	while(i > 0) {
		std::cout << i << std::flush;
		i--;
	}
}

程序会输出

txt
54321

TIP

此处代码中我们使用了自减运算符--i--这段代码的意思是i = i - 1

相应的,存在自增运算符++,则i++这段代码的意思是i = i + 1

循环控制语句

主要有两条语句 breakcontinue,用于控制循环的进行

break

break 语句会跳出循环体,执行紧跟着循环体的下一条语句

例如

Cpp
for(int i = 0; i < 10; i++) {
	if (i == 5) {
		break;
	}
	std::cout << i;
}
std::cout << "ends";

5 次程序正常执行;

i = 5 时会跳出整个循环,直接执行紧跟在后面的 std::cout << "ends";

所以会输出 01234ends

break 只能跳出本层循环,在想在内层循环中跳出双重或者多重循环中,可以使用 goto + 标号的方式来解决

Cpp
for(int i = 0; i < 10; i ++) {
	for(int j = 0; j < 10; j ++) 	{
		if (i * j == 25) {
			goto label;
		}
	}
}
label: std::cout << "25";

这样就可以跳出多重循环

WARNING

使用 goto 会导致程序结构混乱,一度被誉为是大型项目的邪术,应该避免使用

但并不意味goto完全不能使用,在上面的代码中,使用这个语法逻辑也相当清晰,这是因为goto比较适合在多重循环中使用,其他地方我们还是最好使用其他语法代替

continue

continue 语句会跳过本次循环,执行下一次循环,例如

Cpp
for(int i = 0; i < 10; i++) {
	if (i == 5)	{
		continue;
	}
	std::cout << i;
}
std::cout << "ends" << std::flush;

前 5 次程序正常执行;执行到第六次也就是i = 5 时会跳过本次循环, 下一次循环从 i = 6 开始 所以会输出

012346789ends