龙空技术网

C++编程:流程控制语句

尚硅谷教育 136

前言:

而今朋友们对“c语言怎么终止程序运行”大概比较关切,朋友们都想要分析一些“c语言怎么终止程序运行”的相关内容。那么小编在网摘上网罗了一些关于“c语言怎么终止程序运行””的相关文章,希望姐妹们能喜欢,姐妹们一起来了解一下吧!

C++程序执行的流程结构可以有三种:顺序、分支和循环。除了最简单的顺序结构是默认的,分支和循环都需要使用专门的“流程控制语句”来定义。

1. 语句

C++中表示一步操作的一句代码,就叫做“语句”(statement),大多数语句都是以分号“;”结尾的。C++程序运行的过程,其实就是找到主函数,然后从上到下顺序执行每条语句的过程。

1.1 简单语句

使用各种运算符,作用到数据对象上,就得到了“表达式”;一个表达式末尾加上分号,就构成了“表达式语句”(expression statement)。

表达式语句表示,要执行表达式的计算过程,并且丢弃最终返回的结果。

int a = 0; // 变量定义并初始化语句

a + 1; // 算术表达式语句,无意义

++a; // 递增语句,a的值变为1

cout << " a = " << a << endl; // 输出语句

其中第二行a + 1; 是没什么意义的,因为它只是执行了加法操作,却没有把结果保存下来(赋值给别的变量),a的值也没有改变,也没有任何附带效果(比如最后一句的输出)。

最简单的语句,其实是“空语句”,就是只有一个分号的语句:

; // 空语句

这看起来好像没什么用。不过有时候,可能程序在语法上需要有一条语句,而逻辑上什么都不用做;这时就应该用一条空语句来填充。

初学C++,一定不要忘记语句末尾的分号;当然,对于不需要分号的场景,也尽量避免多写分号。

1.2 复合语句

简单语句从上到下按顺序依次执行,这非常符合我们对计算机运行的预期。但是很多场景下,简单的顺序结构远远不能满足逻辑需要:比如我们可能需要按照条件判断,做程序的分支执行;也可能需要将一段代码循环执行多次。这就需要一些“流程控制语句”(比如if、while、for等)来表达更加复杂的操作了。

而对于流程控制语句,逻辑上来说只是一条语句;事实上却可能包含了多条语句、复杂的操作。这就需要用一个花括号“{}”,把这一组语句序列包成一个整体,叫做“复合语句”(compound statement),也叫做“块”(block)。

int i = 0;

while (i < 5) {

int a = i;

++i;

}

这里的while表示一个循环,后面只能跟要循环执行的一条语句;如果我们想写两条语句,就要用花括号括起来,构成“块”。

对于复合语句(块)需要注意:

l 花括号后面不需要再加分号,块本身就是一条语句;

l 块内可以声明变量,变量的作用域仅限于块内部;

l 只有一对花括号、内部没有任何语句的块叫做“空块”,等价于空语句;

2. 条件分支

很多情况下,我们为程序的执行会提供“岔路”的选择机会。一般都是:满足某种条件就执行A操作,满足另一种条件就执行B操作……这样的程序结构叫做“条件分支”。

C++提供了两种按条件分支执行的控制语句:if和switch。

2.1 if

if语句主要就是判断一个条件是否为真(true),如果为真就执行下面的语句,如果为假则跳过。具体形式可以分为两种:一种是单独一个if,一般称为“单分支”;另一种是if … else …,称为“双分支”。

(1)单分支

单分支是最简单的if用法,判断的条件用小括号括起来跟在if后面,然后是如果条件为真要执行的语句。基本形式为:

if (条件判断)

语句

如果条件为假,那么这段代码就会被完全跳过。

我们可以举一个简单示例,判断输入的年龄数值,然后输出一句欢迎词:

#include<iostream>

using namespace std;

int main()

{

cout << "请输入您的芳龄:" << endl;

int age;

cin >> age;

if ( age >= 18 )

{

cout << "欢迎您,成年人!" << endl;

}

cin.get();

cin.get();

}

通常会用一个花括号将if后面的语句括起来,成为一个“块”。现在块里只有一条语句,所以花括号是可以省略的:

if ( age >= 18 )

cout << "欢迎您,成年人!" << endl;

如果要执行的是多条语句,花括号就不能省略;否则if后面其实就只有第一条语句。为了避免漏掉括号出现错误,一般if后面都会使用花括号。

(2)双分支

双分支就是在if分支的基础上,加了else分支;条件为真就执行if后面的语句,条件为假就执行else后面的语句。基本形势如下:

if (条件判断)

语句1

else

语句2

if分支和else分支,两者肯定会选择一个执行。

我们可以在之前程序的基础上,增加一个else分支:

if ( age >= 18 )

{

cout << "欢迎您,成年人!" << endl;

}

else

{

cout << "本程序不欢迎未成年人!" << endl;

}

我们可以回忆起来,之前介绍过的唯一一个三元运算符——条件运算符,其实就可以实现类似的功能。所以条件运算符可以认为是if … else 的一个语法糖。

以下两条语句跟上面的if…else是等价的:

// 条件运算符的等价写法

age >= 18 ? cout << "欢迎您,成年人!" << endl : cout << "本程序不欢迎未成年人!" << endl;

cout << (age >= 18 ? "欢迎您,成年人!" : "本程序不欢迎未成年人!") << endl;

(3)嵌套分支(多分支)

程序中的分支有可能不只两个,这时就需要对if分支或者else分支再做条件判断和拆分了,这就是“嵌套分支”。

简单来说,就是if或者else分支的语句块里,继续使用if或者if…else按条件进行分支。这是一种“分层”的条件判断。

if ( age >= 18 )

{

cout << "欢迎您,成年人!" << endl;

if (age < 35)

{

cout << "加油,年轻人!" << endl;

}

}

else

{

cout << "本程序不欢迎未成年人!" << endl;

if (age >= 12)

{

cout << "少年,好好学习!" << endl;

}

else

{

cout << "小朋友,别玩电脑!" << endl;

}

}

嵌套分支如果比较多,代码的可读性会大幅降低。所以还有一种更加简单的嵌套分支写法,那就是if … else if …,具体形式如下:

if (条件判断1)

语句1

else if (条件判断2)

语句2

else if (条件判断3)

语句3

else

语句n

这种分支的嵌套,本质上只能对else分支进行,而且只能在最底层的分支中才能执行语句。

测试代码如下:

if (age < 12) {

cout << "小朋友,别玩电脑!" << endl;

}

else if (age < 18)

{

cout << "少年,好好学习!" << endl;

}

else if (age < 35)

{

cout << "加油,年轻人!" << endl;

}

else if (age < 60)

{

cout << "加油,中年人!" << endl;

}

else

{

cout << "好好休息,老年人!" << endl;

}

2.2 switch

在一些应用场景中,要判断的条件可能不是范围,而是固定的几个值。比如考试成绩只分“A”“B”“C”“D”四个档位,分别代表“优秀”“良好”“及格”“不及格”。

这个时候如果用if … else会显得非常繁琐,而swith语句就是专门为了这种分支场景设计的。

switch语法基本形式如下:

swith (表达式){

case 值1:

语句1

break;

case 值2:

语句2

break;

default:

语句n

break;

}

这里switch后面的括号里是一个表达式,对它求值,然后转换成整数类型跟下面每个case后面的值做比较;如果相等,就进入这个case指定的分支,执行后面的语句,直到swith语句结束或者遇到break退出。需要注意的是:

case关键字和后面对应的值,合起来叫做一个“case标签”;case标签必须是一个整型的常量表达式;任何两个case标签不能相同;break语句的作用是“中断”,会直接跳转到switch语句结构的外面;如果没有break语句,那么匹配某个case标签之后,程序会从上到下一直执行下去;这会执行多个标签下面的语句,可能发生错误;如果没有匹配上任何case标签的值,程序会执行default标签后面的语句;default是可选的,表示“默认要执行的操作”。

我们可以利用swith写一个判断考试成绩档位,输入一句相应的话:

#include<iostream>

using namespace std;

int main()

{

cout << "请输入您的成绩:" << endl;

char score;

cin >> score;

switch (score)

{

case 'A':

cout << "成绩优秀!" << endl;

break;

case 'B':

cout << "成绩良好!" << endl;

break;

case 'C':

cout << "恭喜!及格了!" << endl;

break;

case 'D':

cout << "欢迎下次再来!" << endl;

break;

default:

cout << "错误的成绩输入!" << endl;

break;

}

cin.get();

cin.get();

}

3 循环

可以重复执行一组操作的语句叫做“循环”,有时也叫作“迭代”。循环一般不能无限进行下去,所以会设置一个终止的判断条件。

C++中的循环语句,有while、do while和for三种。

3.1 while

while只需要给定一个判断条件,只要条件为真,就重复地执行语句。形式如下:

while (条件)

语句

要执行的语句往往会有多条,这就需要用花括号将它们括起来。这个块一般被称为“循环体”。

一般来说,用来控制while循环的条件中一定会包含变量,通常叫做“循环变量”;而它或者在条件中变化,或者在循环体中变化,这样才能保证循环能够终止退出。

比如我们可以用一个循环输出10次“Hello World”,并且打印出当前循环次数:

#include<iostream>

using namespace std;

int main()

{

cout << "循环开始...\n" << endl;

int i = 1;

while (i <= 10)

{

cout << "Hello World!" << endl;

cout << "现在是第" << i << "次循环\n" << endl;

++i;

}

cout << "循环结束!" << endl;

cin.get();

}

这里需要注意,循环体最后的 ++i一定不能漏掉。如果没有这条语句,i的值就不会更改,循环就永远不会退出。

3.2 do while

do while和while非常类似,区别在于do while是先执行循环体中的语句,然后再检查条件是否满足。所以do while至少会执行一次循环体。

do while语法形式如下:

do

语句

while (条件)

我们可以接着之前while循环的代码继续测试:

do

{

cout << "现在是倒数第" << --i << "次循环" << endl;

cout << "GoodBye World!\n" << endl;

} while (i > 1);

由于之前的变量i已经做了10次递增,因此do wihle开始时i的值为11。进入循环体直接输出内容,每次i递减1,直到i = 1时退出循环。

3.3 for

通过while和do while可以总结出来,一个循环主要有这样几个要素:

l 一个条件,用来控制循环退出;

l 一个循环体,用来定义循环要执行的操作;

而一般情况下,我们都是通过一个循环变量来控制条件的,这个变量需要随着循环迭代次数的增加而变化。while和do while的循环变量,都是在循环体外单独定义的。

for是用法更加明确的循环语句。它可以把循环变量的定义、循环条件以及循环变量的改变都放在一起,统一声明出来。

(1)经典for循环

for循环的经典语法形式是:

for (初始化语句; 条件; 表达式)

语句

关键字for和它后面括号里的部分,叫做“for语句头”。

for语句头中有三部分,用分号分隔,主要作用是:

初始化语句负责初始化一个变量,这个变量值会随着循环迭代而改变,一般就是“循环变量”;中间的条件是控制循环执行的关键,为真则执行下面的循环体语句,为假则退出。条件一般会以循环变量作为判断标准;最后的表达式会在本次循环完成之后再执行,一般会对循环变量进行更改;

这三个部分并不是必要的,根据需要都可以进行省略。如果省略某个部分,需要保留分号表示这是一个空语句。

我们可以用for循环语句,实现之前输出10次“Hello World”的需求:

#include<iostream>

using namespace std;

int main()

{

for (int i = 1; i <= 10; i++)

{

cout << "Hello World!" << endl;

cout << "现在是第" << i << "次循环!\n" << endl;

}

cin.get();

}

(2)范围for循环

C++ 11新标准引入了一种更加简单的for循环,这种语句可以直接遍历一个序列的所有元素。这种for循环叫做“范围for循环”。语法形式如下:

for (声明: 序列表达式)

语句

这里for语句头中的内容就很简单了,只需要声明一个变量,后面跟上一个冒号(注意不是分号),再跟上一个序列的表达式就可以了。所谓“序列”,其实就是一组相同类型的数据对象排成了一列来统一处理;所以这个声明的意思,其实就是从序列中依次取出所有元素,每次都赋值给这个变量。

所以范围for循环的特点就是,不需要循环变量,直接就可以访问序列中的所有元素。

// 范围for循环

for (int num : {3, 6, 8, 10})

{

cout << "序列中现在的数据是:" << num << endl;

}

这里用花括号把一组数括起来,就构成了最简单的序列:{3, 6, 8, 10}。后面将要介绍的数组,以及vector、string等类型的对象,也都是序列。

3.4 循环嵌套

循环语句和分支语句一样,也是可以进行嵌套的。具体可以while循环中嵌套while,可以for循环中嵌套for,也可以while、do while和for混合嵌套。因为for的循环变量定义更明确,所以一般用for的循环嵌套会多一些。

for (int i = 0; i < 3; i++)

{

for (int j = 0; j < 5; j++)

{

cout << "Hello World! i = " << i << ", j = " << j << endl;

}

}

循环嵌套之后,内层语句执行的次数,将是外层循环次数和内层循环次数的乘积。这会带来大量的时间消耗,使程序运行变慢,所以使用嵌套循环要非常谨慎。

下面是一个使用双重for循环,打印输出“九九乘法表”的例子。

#include<iostream>

using namespace std;

int main()

{

// i表示行数,j表示列数

for (int i = 1; i < 10; i++)

{

for (int j = 1; j <= i; j++) {

cout << j << " × " << i << " = " << i * j << "\t";

}

cout << endl;

}

cin.get();

}

这里使用内外两层for循环,实现了一个二维“表”的输出。后面我们会看到,循环嵌套对于处理多维数据非常有用。

4 跳转

在流程控制语句中还有一类“跳转语句”,主要用来中断当前的执行过程。C++中有四种跳转语句:break,continue,goto以及return。

4.1 break

break语句表示要“跳出”当前的流程控制语句,它只能出现在switch或者循环语句(while、do while、for)中。当代码中遇到break时,会直接中断距离最近的switch或者循环,跳转到外部继续执行。

int i = 0;

while (true)

{

cout << " Hello World! " << endl;

cout << " 这是第" << ++i << "次输出\n" << endl;

if (i >= 5)

{

break;

}

}

如果循环条件永远为真,那么循环体中一定要有break,保证在某种情况下程序可以退出循环。

4.2 continue

continue语句表示“继续”执行循环,也就是中断循环中的本次迭代、并开始执行下一次迭代。很明显,continue只能用在循环语句中,同样针对最近的一层循环有效。

continue非常适合处理需要“跳过”某些情况的场合。

// 逢7过

for (int num = 1; num < 100; num++)

{

cout << "\t";

// 如果是7的倍数,或者数字中有7,则跳过

if (num % 7 == 0 || num % 10 == 7 || num / 10 == 7)

continue;

cout << num;

// 如果是10的倍数,则换行

if (num % 10 == 0)

cout << endl << endl;

}

上面模拟了一个经典的小游戏“逢7过”,如果遇到7的倍数比如7、14、21,或者数字中有7比如17、27、71,都要跳过。

4.3 goto

goto语句表示无条件地跳转到程序中的另一条语句。goto的语法形式为:

goto 标签;

这里的“标签”可以认为是一条语句的“名字”,跟变量类似,只不过它是指代一条语句的标识符。定义标签也非常简单,只要在一条语句前写出标识符,然后跟上冒号就可以了,比如:

begin: int a = 0;

下面是一个具体的例子:

int x = 0;

cout << "程序开始..." << endl;

begin:

do

{

cout << " x = " << ++x << endl;

} while (x < 10);

if (x < 15) {

cout << "回到原点!" << endl;

goto begin;

}

cout << "程序结束!" << endl;

由于goto可以任意跳转,所以它非常灵活,也非常危险。一般在代码中不要使用goto。

4.4 return

return是用来终止函数运行并返回结果的。之前的Hello World程序中就曾经介绍,主函数最后的那句 return 0; 就是结束主函数并返回结果,一般这句可以省略。

而在自定义的函数中,同样可以用return来返回。

5. 应用案例

综合利用分支和循环语句,就可以实现很多有趣的功能。

5.1 判断质数

质数也叫素数,是指一个大于1的自然数,因数只有1和它自身。质数是数论中一个经典的概念,很多著名定理和猜想都跟它有关;质数也是现代密码学的基础。

判断一个数是否为质数没有什么规律可言,我们可以通过验证小于它的每个数能否整除,来做暴力求解。下面是一段判断质数、并输出0~100内所有质数的程序:

#include<iostream>

using namespace std;

// 定义一个判断质数的函数,用return返回判断结果

bool isPrime(int num)

{

int i = 2;

while (i < num)

{

if (num % i == 0) return false;

++i;

}

return true;

}

int main()

{

cout << "请输入一个自然数(不超过20亿):" << endl;

int num;

cin >> num;

if (isPrime(num))

{

cout << num << "是质数!" << endl;

}

else

{

cout << num << "不是质数!" << endl;

}

cout << "\n=========================\n" << endl;

cout << "0 ~ 100 内的质数有:" << endl;

for (int i = 2; i <= 100; i++)

{

if (isPrime(i))

cout << i << "\t";

}

cout << endl;

cin.get();

cin.get();

}

5.2 猜数字

猜数字是一个经典的小游戏,程序随机生成一个0~100的数字,然后由用户输入来猜测。如果猜对,输出结果并退出;如果不对,则提示偏大还是偏小。我们可以对猜的次数做限制,比如一共5次机会。

#include<iostream>

using namespace std;

int main()

{

cout << "=========猜数字========" << endl;

cout << "规则:输入0~100的整数,有5次机会\n" << endl;

// 以当前时间为随机数种子,生成一个0~100的伪随机数

srand(time(0));

int target = rand() % 100;

int n = 0; // 猜的次数

while (n < 5)

{

cout << "请输入0~100的整数:" << endl;

int num;

cin >> num;

if (num == target)

{

cout << "恭喜你,猜对了! 幸运数字是:" << target << endl;

break;

}

else if (num > target)

cout << "数字太大了!再猜一遍!" << endl;

else

cout << "数字太小了!再猜一遍!" << endl;

++n;

}

if (n == 5)

cout << "已经猜过5遍,没有猜中!欢迎下次再来!" << endl;

cin.get();

cin.get();

}

标签: #c语言怎么终止程序运行