第3章 基本控制结构


第3章 基本控制结构



在程序设计语言中控制结构用于指明程序的执行流程。C++语言提供的基本控制结构包括\(3\)种类型:
(1)顺序结构:按照先后顺序依次执行程序中的语句。
(2)选择结构:按照给定条件有选择地执行程序中的语句。
(3)循环结构:按照给定规则重复地执行程序中的语句。
本章对实现C++程序基本控制结构的各种相关语句进行详细的介绍。



C++语句



语句是C++程序中的基本功能单元。任何一条C++语句都会为完成某项任务而进行相关操作。就像自然语言中的句子以句号结束一样,C++语句通常以分号作为结束标志。例如,在表达式i+5的后面添加分号,使其变为

i+5;

就构成了一条合法的C++语句。

C++语句按照不同功能大体分为\(6\)种类型,它们是:
(1)声明语句:用于对程序中的各种实体进行声明、定义及初始化。只中面
(2)表达式语句:用于对程序中的数据进行具体操作和处理。
(3)选择语句:用于实现程序的选择结构。
(4)循环语句:用于实现程序的循环结构。
(5)跳转语句:用于实现程序执行流程的转移。
(6)复合语句:用于表示程序中的语句块。
应当指出的是,C++中并不存在赋值语句和函数调用语句,赋值和函数调用都属于表达式而不是语句。



顺序结构



顺序结构是C++程序中执行流程的默认结构。在一个没有选择和循环结构的程序中,语句将按照书写的先后顺序,从左向右,自上而下依次执行。除了选择、循环和跳转语句外,其他C++语句都可以看作实现程序顺序结构的语句。


声明语句

声明语句又称为说明语句,它可以用来对程序中出现的各种名称进行声明。这些名称通常是表示变量、常量、函数、结构、类、对象等实体的标识符。在C++程序中,一个名称在使用之前必须先被声明。声明的目的是告诉编译器某个名称所指代的实体类型。使用声明语句能够在程序中进行如下操作:

(1)变量声明,例如:

char ch;                //声明和定义char型变量
int count=1;            //声明、定义和初始化int型变量
extern int error_num;   //声明int型变量

(2)常量声明,例如:

const int MAX_LEN =128;     //声明、定义和初始化int型常量
const double pi = 3.14159;  //声明、定义和初始化 double型常量

(3)函数声明,例如:

double sqrt(double);   //声明函数
int max(int a,int b){ return a>b?a:b; } //声明和定义函数

(4)类型声明,例如:

typedef unsigned int ID;       //声明和定义类型
enum Color{ RED,GREEN,BLUE }; //声明和定义枚举
struct Date{ int y,m,d; };     //声明和定义结构
class Employee;                //声明类

声明语句可以完成的工作不仅仅局限于为名称指定类型,上述大多数声明语句同时也是定义语句。所谓定义,就是对某个名称所指代的实体进行具体描述。例如,与变量ch对应的实体是内存中用来存储一个字符型数据的空间;与常量pi对应的实体是一个double型数值\(3.14159\);与函数max对应的实体是函数体内的代码;与结构Date对应的实体是一个新的结构类型。在上面的声明语句中只有

extern int error_num;
double sqrt(double);
class Employee;

是单纯的名称声明而没有进行实体定义工作。因此,与名称error_numsqrtEmployee 对应的实体必须在程序中其他地方被定义,即int型变量error_num的内存空间必须由另外的声明语句分配;函数sqrt的代码必须由另外的声明语句给出;类Employee的具体结构也必须由另外的声明语句描述。例如:

int error_num = 1; //int型变量 error_num的定义
double sqrt(double){ /*函数 sqrt的代码 */ }
class Employee { /* 类 Employee的具体定义 */ };

C++语言规定:一个实体的定义只能出现一次,而其声明却可以出现多次。同一实体的多个声明必须在类型上保持一致。下面的声明语句中含有两处错误:

int count;
int count;   //错误:count被重复定义
extern int error_num;
extern long error_num; //错误:error_num两次声明类型不一致

而在下面的声明语句则没有错误:

extern int error_num;
extern int error_num;  //对error_num声明两次且类型一致

另外,使用声明语句还可以在定义变量时对其进行初始化。例如,声明语句int count=1;不仅为int型变量count分配了合适的内存空间,而且还将这块空间所表示的数值初始化为\(1\)

将声明(包括定义)作为一种语句处理是C++对C语言的语法进行的扩充。在C++中,声明语句可以出现在任何其他语句能够出现的地方,因此能做到在需要使用某个变量的恰当位置对其进行声明、定义及初始化,给程序员带来了很大的方便。


表达式语句

C++中所有对数据的操作和处理工作都是通过表达式语句来完成的。表达式语句的语法格式为:

<表达式>;

也就是说,在任何合法的C++表达式后面添加一个分号便构成了一条表达式语句。

使用表达式语句可以进行的操作通常包括:

(1)赋值操作。例如:

count=5; //将count赋值为5
i=1,j=2;//将i,j分别赋值为1,2
a=b+c;   //将b+c的值赋给a
a=b=c;   //先将c的值赋给b,再将b的值赋给a

(2)复合赋值操作。例如:

a+=9;  //将a+9的值赋给a
b*=c;  //将b*c的值赋给b

(3)增量、减量操作。例如:

i++; //将i增1
--j; //将j减1

(4)函数调用操作。例如:

abs(x);   //调用函数 abs
sqrt(9);  //调用函数 sqrt
fun(a,b); //调用函数 fun

(5)输入输出操作。例如:

cout<<a+b; //输出a+b的值
cin>>i>>j; //输入数据到i,j

基本输入输出

一个程序通常会向用户输出一些信息,一般也会要求用户输入一些信息。c++程序的输入输出操作是通过标准库中的输入/输出流对象来完成的。

在头文件iostream中定义了代表屏幕的标准输出流对象cout和代表键盘的标准输入流对象cincincout具有强大的输入输出功能和极为灵活的用法。在程序中使用cincout之前,应首先加入预处理命令:#include<iostream>,以包含标准头文件iostream

使用cout进行数据输出操作的一般格式为:

cout << Expr;

这是一条表达式语句。其中,Expr代表一个表达式;<<称为插入运算符。整条语句的含义是:将表达式Expr的值输出(显示)到屏幕上当前光标所在位置。例如,下面语句的执行结果是在屏幕的当前光标处显示数值\(5\)

int a=5;
cout << a;

cout在用法上的灵活性主要表现为:它可以用来对C++中所有的常用数据类型进行输出操作。例如:

long lvar=1000;
cout << lvar;  //输出long型变量
double dvar=0.5;
cout << dvar;  //输出 double型变量
cout<<10;      //输出整型常量
cout<<'c';     //输出字符型常量
cout<<"This is a string.\n"; //输出字符串常量

cout还允许在一条语句中连续使用插入运算符来输出多项数据。例如:

int i=5,j=10;
cout<<i<<j;

将变量ij的值依次显示在屏幕上。应该注意的是,cout并不会在数据项ij之间加入任何分隔字符。这样,上述语句的输出结果将成为:

510

因此,为了方便用户阅读,程序员在使用cout进行多项数据的输出时有必要加入一些分隔字符。常用的分隔字符有空格(字符常量)和水平制表(字符常量\t)。例如,将上面的输出语句改为:

cout<<i<<' '<<j;  //在i,j之间输出空格

则输出结果将变成:

5 10

使用水平制表符\t可以将多项数据对齐显示到屏幕的不同区域(每个区域之间的距离通常为\(8\)个字符),例如:

cout<<"No.1"<<'\t'<<"No.2"<<'\t'<<"No.3"<<'\n';
cout<<"111"<<'\t'<<"222"<<'\t'<<"333"<<'\n';

将输出下面的结果:

No.1 No.2 No.3
111  222  333

C++中提供了两种进行换行输出的方法:

(1)使用换行字符\n
(2)使用输入/输出操作符endl

两者实现的功能完全相同,都是使随后的输出内容从新的一行开始显示。例如,语句

cout<<"My name is Jone.\n"  //使用换行字符'\n'
    <<"The ID is"<<endl<<2; //使用操作符 endl

的输出结果为:

My name is Jone.
The ID is
2

使用cin进行数据输入操作的一般格式为:

cin>>Var;

这也是一条表达式语句。其中,Var代表一个变量;>>称为提取运算符。整条语句的含义是:程序将暂时中止执行,等待用户从键盘上输入一个数据。如果用户键人了一个有效的数据并按下了回车键,程序就将此数据保存到变量Var中,并继续执行后续语句。例如,下面的语句要求用户为变量a输入一个int型数值:

int a;
cin >> a;

cout相同,cin也可以用来对C++中所有的常用数据类型进行输入操作。例如:

long lvar;
cin >> lvar;   //输入long型变量
double dvar;
cin >> dvar;   //输入 double型变量
char ch;
cin >> ch;     //输入字符型变量
char str[128]; //输入字符串(即字符数组)
cin >> str;

同样,cin也允许在一条语句中连续使用提取运算符来输入多项数据。例如,语句

int i,j;
cin >> i >> j;

要求用户连续输入两个int型数值,并将它们分别保存到变量ij中。在进行多项数据的连续输入时,应键入空白字符(包括空格键,回车键和Tab键)将相邻的两项数据分隔开。例如,假设用户要为变量i输入5,为变量j输入10,则应该键入:

5<SP>10<CR>

其中,<SP>表示空格键,<CR>表示回车键。

注意:用户输入数据的类型必须与保存该数据的变量类型相匹配,否则将得到错误的结果。


例3.1


下面用一个完整的程序来演示 cincout的用法:


习题3



选择题


1.下列选项中属于C++语句的是____。
A);
B)a=17
C)i+5
D)cout<<'\n'


2.下列声明语句中没有起到定义作用的是____。
A)int count;
B)const double pi=3.14159;
C)in max(int a,int b){ return a>b ? a : b; }
D)extern long index;


3.下面程序的输出结果是____。

#include<iostream>
using namespace std;
int main()
{
	int a=2,b=-1,c=2;
	if(a<b)
		if(b<0) c=0;
	else c+=1;
	cout<<c<<endl;
}

A)0
B)1
C)2
D)3


4.下列for语句的循环次数为____。

for(int i=0,x=0;!x&&i<=5;++i);

A)\(5\)
B)\(6\)
C)\(7\)
D)无穷次


5.下列语句段将输出字符'*'的个数为____。

int i=100;
while(1)
{
	i--;
	if(i==0) break;
	cout<<'*';
}

A)\(98\)
B)\(99\)
C)\(100\)
D)\(101\)


6.下面程序的输出结果是____。

#include<iostream>
using namespace std;
int main()
{
	int s;
	for(int k=2;k<6;k+=2)
	{
		s=1;
		for(int j=k;j<6;++j) s+=j;
	}
	cout<<s<<endl;
	return 0;
}

A)9
B)1
C)11
D)10


7.下面程序的输出结果是____。

#include<iostream>
using namespace std;
int main()
{
	int n=10;
	while(n>7)
	{
		n--;
		cout<<n<<',';
	}
	cout<<endl;
	return 0;
}

A)10,9,8,
B)9,8,7,
C)10,9,8,7,
D)9,8,7,6,


8.下列关于do...while语句的叙述中,正确的是____。
A)do...while语句所构成的循环不能用其他语句构成的循环来代替
B)do...while语句所构成的循环只能用break语句跳出
C)do...while语句所构成的循环只有在while后面的表达式非零时才结束
D)do...while语句所构成的循环只有在while后面的表达式为零时才结束


9.下面程序的输出结果是____。

#include<iostream>
using namespace std;
int main()
{
	int x;
	for(int i=1;i<=100;++i)
	{
		x=i;
		if(++x%2==0)
			if(++x%3==0)
				if(++x%7==0)
					cout<<x<<',';
	}
	cout<<endl;
	return 0;
}

A)39,81,
B)42,84,
C)26,68,
D)28,70,


10.下列关于break语句的叙述中,不正确的是____。
A)break语句可用在循环体中,它将使执行流程跳出本层循环体
B)break语句可用在switch语句中,它将使执行流程跳出当前switch语句
C)break语句可用在if语句中,它将使执行流程跳出当前if语句
D)break语句在一层循环体中可以出现多次


填空题


1.C++语言中用于控制程序执行流程的三种基本结构是 ____ 、 ____ 、 ____ 。


2.下面语句段的输出结果是____。

int x=0,y=2,z=3;
switch(x)
{
	case 0: switch(y)
	{
		case 1: cout<<'*'; break;
		case 2: cout<<'%'; break;
	}
	case 1: switch(z)
	{
		case 1: cout<<'$'; break;
		case 2: cout<<'*'; break;
		default: cout<<'#';
	}
}

3.下面语句段的输出结果是____。

int k=1,n=10,m=1;
while(k<=n)
{
	m*=2;
	n--;
}
cout<<m<<endl;

4.当执行完下面语句段后,i的值是 ____ 、j的值是 ____ 、k的值是 ____。

int a=10,b,c,d,i,j,k;
b=c=d=5;
i=j=k=0;
for(;a>b;++b) i++;
while(a>++c) j++;
do { k++; } while(a>d++);

5.将下面的语句断(a)补充完整,使其和语句段(b)在功能上完全等价:
(a)

double s=0.0;
________;
int k=0;
do
{
	s+=d;
	________;
	d=1.0/(k*(k+1));
}while(________);

(b)

double s=1.0;
for(int k=1;k<=10;++k) s+=1.0(k*(k+1));

编程题


1.编写程序,实现输入一个整数,判断其能否被\(3,5,7\)整除,并输出以下信息之一:
(a)能同时被\(3,5,7\)整除;
(b)能被其中两个数(要输出是哪两个数)整除;
(c)不能被\(3,5,7\)中的任一个数整除。


2.编写程序,要求由用户输入任意三个实数,然后求出其中的最大值和最小值。


3.编写摄氏温度与华氏温度的换算程序。要求用户输入温度数值并指明该数值表示摄氏温度(C)还是华氏温度(F),程序将根据不同的输入(摄氏或华氏)进行不同的换算。例如,用户输入40.2C,程序输出104.36F,或用户输入104.36F,程序输出40.2C
已知,换算公式为:摄氏温度\(=\frac{5}{9}(\)华氏温度\(-32)\)


4.编写程序,求\(1-3+5-7+\cdots-99+101\)的值


5.编写程序,根据公式\(e=1+\frac{1}{1!}+\frac{1}{2!}+\frac{1}{3!}+\frac{1}{4!}+\cdots\)计算\(e\)的值。要求:
(a)使用for循环,计算到公式的前\(50\)项。
(b)使用while循环,直到公式最后一项的值小于\(10^{-4}\)为止。


6.编写程序,输出从公元\(1600\)年到公元\(2000\)年中所有闰年的年份。要求每行输出\(5\)个年份。判断公元年份是否为闰年的条件是:
(a)年份如能被\(4\)整除,而不能被\(100\)整除,则为闰年。
(b)年份如能被\(400\)整除也是闰年。


7.编写程序,求“水仙花数”。所谓“水仙花数”是指一个三位数,其各位数字的立方和等于该数本身。例如,\(153\)是水仙花数,因为\(1^3+5^3+3^3=153\)


8.编写程序,求\(1000\)之内的所有“完全数”。所谓“完全数”是指一个数恰好等于其因子之和。例如,\(6\)是完全数,因为\(1+2+3=6\)


9.使用迭代法变成求\(x=\sqrt a\)。求平方根的迭代公式为:

\[x_{n+1}=\frac{1}{2}(x_n+\frac{a}{x_n}) \]


10.编写程序,使用循环语句打印如下图案:

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


习题参考答案



选择题


1.A
2.D
3.C
4.B
5.B
6.D
7.B
8.D
9.D
10.C


填空题


1.顺序结构、选择结构、循环结构
2.%#
3.1024
4.546
5.

double d=1.0
++k
k<=10

编程题


1.完整代码如下:

#include<iostream>
using namespace std;
int main(){
	bool f3=0,f5=0,f7=0;
	int x; scanf("%d",&x);
	if(x%3==0) f3=1;
	if(x%5==0) f5=1;
	if(x%7==0) f7=1;
	if(f3&&f5&&f7)
		printf("%d能同时被3,5,7整除\n",x);
	else if(!f3&&!f5&&!f7)
		printf("%d不能被3,5,7中的任一个数整除\n",x);
	else {
		if(f3&&f5) printf("%d能被其中两个数(3,5)整除\n",x);
		if(f3&&f7) printf("%d能被其中两个数(3,7)整除\n",x);
		if(f5&&f7) printf("%d能被其中两个数(5,7)整除\n",x);
	}
	return 0;
}

2.完整代码如下:

#include<iostream>
using namespace std;
int main(){
	double x,y,z;
	scanf("%lf %lf %lf",&x,&y,&z);
	printf("%lf\n",max(x,max(y,z)));
	printf("%lf\n",min(x,min(y,z)));
	return 0;
}

3.完整代码如下:

#include<iostream>
using namespace std;
int main(){
	double x; char ch;
	scanf("%lf%c",&x,&ch);
	if(ch=='C')
		cout<<9.0*x/5.0+32<<'F'<<endl;
	if(ch=='F')
		cout<<5.0/9.0*(x-32)<<'C'<<endl;
	return 0;
}

4.完整代码如下:

#include<iostream>
using namespace std;
int main(){
	int f=1,ans=0;
	for(int i=1;i<=101;i+=2){
		ans+=i*f;
		f*=-1;
	}
	printf("%d",ans);
	return 0;
}

5.完整代码如下:
(a)

#include<iostream>
using namespace std;
int main(){
	double e=1,res=1;
	for(int i=1;i<=50;++i){
		res*=i;
		e+=1.0/res;
	}
	cout<<e;
	return 0;
}

(b)

#include<iostream>
using namespace std;
int main(){
	double e=1,x=1;
	int cnt=1;
	while((1.0/x)>=0.0001){
		e+=1.0/x;
		x*=++cnt;
	}
	cout<<e;
	return 0;
}

6.完整代码如下:

#include<iostream>
using namespace std;
int main(){
	int cnt=0;
	for(int i=1600;i<=2000;++i)
		if((i%4==0 && i%100!=0) || (i%400==0)){
			printf("%d ",i);
			if(++cnt==5){ cnt=0; puts(""); }
		}
	return 0;
}

7.完整代码如下:

#include<iostream>
using namespace std;
int main(){
	for(int i=1;i<=9;++i)
		for(int j=0;j<=9;++j)
			for(int k=0;k<=9;++k)
				if(i*i*i+j*j*j+k*k*k == i*100+j*10+k)
					printf("%d\n",i*100+j*10+k);
	return 0;
}

8.完整代码如下:

#include<iostream>
using namespace std;
int main(){
	for(int i=1;i<=1000;++i){
		int res=0;
		for(int j=1;j<i;++j)
			if(i%j==0) res+=j;
		if(res==i) printf("%d\n",i);
	}
	return 0;
}

9.前后两次求出的x的差的绝对值小于\(10^{-5}\),完整代码如下:

#include<iostream>
#include<cmath> 
using namespace std;
int main(){
	double a,xnow,xpre=0;
	scanf("%lf",&a);
	xnow=a/2.0;
	while(fabs(xnow-xpre)>=0.00001){
		xpre=xnow;
		xnow=1.0/2.0*(xnow+a/xnow);
	}
	cout<<xnow;
	return 0;
}

10.完整代码如下:

#include<iostream>
using namespace std;
int main(){
	for(int i=1;i<=4;++i){
		for(int j=4-i;j;--j) printf(" ");
		for(int j=1;j<=i*2-1;++j) printf("*");
		puts("");
	}
	for(int i=1;i<=3;++i){
		for(int j=1;j<=i;++j) printf(" ");
		for(int j=1;j<=(4-i)*2-1;++j) printf("*");
		puts("");
	}
	return 0;
}
原文地址:https://www.cnblogs.com/Potrem/p/2021_CPP_3.html