第3章

顺序结构程序设
计


从田忌赛马说起——
— 

齐国的大将田忌常同齐威王进行跑马比赛。赛前,双方各下赌注,每次比赛共设三局, 
胜两次及以上为赢家。然而,每次比赛,田忌总是输给齐威王。

这天,田忌赛马时又输给了齐威王。回家后,田忌十分郁闷,他把赛马失败的事情告诉
了孙膑。孙膑是大军事家孙武的后代,足智多谋,熟读兵书战策,深谙兵法,只是曾被魏国将
军庞涓谋害造成双腿残疾,不能率兵打仗。他被田忌救到齐国后,很受器重。田忌待他为上
宾,请他当了军师。

孙膑说:“ 将军与大王的马我看了。其实,将军的三等马匹与大王的都差那么一点儿。
您第一局派出的是上等马与大王的上等马比赛,第二局派中等马与大王的中等马比赛,第三
局派下等马与大王的下等马比赛。您这样总按常规派出马与大王的马比赛,您永远会输。” 
田忌不解地问:“ 不这样,又怎么办呢?” 孙膑对田忌说:“ 下次赛马时,您照我说的办法派出
马匹,一定会取胜的,您只管多下赌注就是了。田(”) 忌听了,大喜。这次他主动与齐威王相约, 
择日再进行赛马。齐威王听了,不屑地说:“ 田将军又想给寡人送银子了,再比,将军也
是输。” 

赛马这一天到了。双方的骑士和马匹都来到赛马场上。齐威王和田忌在看台上饶有兴
致地观看比赛。孙膑也坐着车子,坐在田忌的身旁。

赛马开始了,第一局田忌派出了自己的下等马,对阵齐威王的上等马。结果可想而知, 
田忌输掉了第一局。齐威王十分得意。第二局,田忌派出了自己的上等马对阵齐威王的中
等马。结果,田忌赢了第二局。第三局,田忌派出自己的中等马对阵齐威王的下等马,田忌
又赢了第三局。三局两胜,田忌第一次在赛马比赛中战胜了齐威王。由于事先田忌下了很
大的赌注,他把前几次输掉的银子都赚了回来,还略有盈余。

这是一篇寓意深刻的寓言故事,引自《史记
· 
孙子吴起列传》。这个故事告诉人们要有
全局观念,如果能够在整体上取得重大胜利,就要舍得局部付出一点点牺牲和损失。在整体
实力与对手相等或者略低于对手的时候,要想取得胜利,那就要看谁会巧妙地排兵布阵了, 
也就是比赛的顺序。齐威王的比赛的顺序就是上等马、中等马、下等马,而田忌的参赛顺序
则是下等马、上等马、中等马,那结果可想而知,大概率会获得三局两胜。不同的顺序导致了
不同的结果。所以我们做事情更要遵循事物的发展顺序和内在规律,才能事半功倍。编写
程序亦是如此,结合事物内在的规律和程序目标,合理选择程序设计的基本结构。

顺序结构、选择结构和循环结构是程序设计的3种基本结构。用这3种基本结构能够


42 C 语言程序设计
描述程序设计的任何算法和问题。这3种基本结构是结构化程序设计的基础。
本章将介绍顺序结构程序的设计,整型、实型、字符型的数据输入输出的格式及复合语
句等。
3.1 顺序结构的程序特点
【例3.1】 求两整数的和。 
main( ) 
{ int a,b, x; 
printf("请为a,b 输入值:"); 
scanf("%d%d",&a,&b); 
x=a+b; 
printf("x=%d\n",x); 
}
运行结果为: 
请为a,b 输入值::20 |7 ↙ 
x=27 
这里,“|”表示空格,“↙”表示按Enter键。
上述程序完成的功能:从键盘输入两个整数,通过计算,输出此两整数的和。
图3.1 顺序结构的流
程图和N-S图
该程序在执行时,函数体(即“{”和“}”之间的部分)中的语
句是按书写顺序从上到下,一句一句地被执行的。
这种按语句出现的先后顺序逐条被执行的程序结构就称为
顺序结构。
顺序结构程序的流程图和N-S图如图3.1所示。
顺序结构程序的特点如下。
(1)程序一般由下面几部分组成: 
定义变量; 
输入数据或赋值; 
对数据进行操作(分析、运算); 
输出结果。
(2)顺序结构的程序在执行过程中严格按照语句书写的先
后顺序逐一执行。每个语句都会被执行,并且只执行一次。
(3)顺序结构的程序结构简单,易于理解。
3.2 赋值语句
赋值语句由赋值表达式加上分号构成。例如: 
a=3.14; 
视频

第3 章 顺序结构程序设计 43 
而a=3.14则是赋值表达式。
再如: 
a=5,b=7; 
是赋值语句。而 
a=5,b=7 
则是两个赋值表达式。
要注意变量定义中赋初值和赋值语句的区别:在变量定义中,不允许连续给变量赋初
值,而赋值语句允许连续赋值。例如: 
int x=y=z=5; 
是错误的声明方式(写成intx=5,y=5,z=5;是正确的)。 
int x,y,z; 
x=y=z=5; 
则是正确的赋值方式。赋值语句: 
x=y=z=5; 
相当于 
x=(y=(z=5)); 
3.3 数据输入输出
数据输入是指把计算机需要的数据从输入设备(通常是键盘)送给计算机。数据输出是
把计算机内存中的数据送到外部设备上,通常是显示器上。在C语言中,没有输入输出语
句,输入和输出操作是通过调用库函数来完成的。
C语言中的标准输入输出库函数有printf(格式输出)、scanf(格式输入)、putchar(输出
字符)、getchar(输入字符)、puts(输出字符串)、gets(输入字符串)等。本节介绍前4个最基
本的输入输出函数。
注意:在调用标准输入输出库函数时,要用到“stdio.h”头文件,程序开头应有以下编译
预处理命令: 
#include <stdio.h> 
或 
#include "stdio.h" 
stdio是standardinput&output的缩写。由于printf和scanf函数使用频繁,TurboC2.0 
允许(TurboC++ 3.0、VC++ 6.0等不允许)在使用这两个函数时可以不加#include命令。
3.3.1 格式输出函数———printf函数
1.printf函数的一般格式 
printf函数的一般格式如下:

44 C 语言程序设计 
printf(格式控制字符串,输出表列); 
例如: 
printf("Welcome!"); 
printf("The numbers: %d,%f\n",k,y); 
说明: 
(1)格式控制字符串必须用双引号括起来。格式控制字符串由3类内容组成。
第一类是普通字符。函数将它们原样输出到屏幕上。
第二类是转义字符。在输出时按其含义完成相应的功能。
第三类是格式说明。由“%”和格式字符组成,如%d、%f等。它指定要输出的数据类型。
(2)输出表列是需要输出的变量、常量、表达式等,输出表列中参数的个数可以是0个
或若干个,当超过一个时用逗号分隔。输出表列和格式说明在个数和类型上要一一匹配。
【例3.2】 对普通字符、转义字符、格式说明以及个数和类型一一匹配关系进行说明。
如果k=10,y=25.6,则上述语句输出结果为: 
The numbers:10,15.600000 
2.printf函数的格式字符
不同的数据输出时使用不同的格式字符。printf函数中的格式字符如表3.1所示。
表3.1 printf函数的格式字符
输出类型格式字符说 明
整型数据
d,i 输出带符号的十进制整数(正数不输出正号) 
o 输出无符号的八进制整数(不输出前缀0) 
u 输出无符号的十进制整数
x,X 输出无符号的十六进制整数(不输出前缀0x),用x输出十六进制整数时的
a~f以小写形式输出,用X时以大写字母形式输出
字符型数据c 输出一个字符
s 输出一个字符串
实型数据
f 以小数形式输出单、双精度实数,隐含输出6位小数
e,E 以指数形式输出实数,用e时指数以“e”表示(如1.6e+03),用E 时指数以
“E”表示(如1.6E+03) 
g,G 自动选用%f和%e中输出宽度较短的一种形式输出实数,且不输出无意义
的0。用G时,若以指数形式输出,则指数以大写表示

第3 章 顺序结构程序设计 45 
例3.2就是应用了格式字符d和f,即格式说明%d和%f。
对于格式字符,下面再说明几种情况。
(1)输出实数。
使用格式%f输出,整数部分全部如数输出,小数部分按6位小数输出。但并非全部数
字都是有效数字,float型实数的有效数字是前7位,double型实数的有效数字是前15位或
16位。
【例3.3】 输出单精度实数,观察有效位数。 
main( ) 
{ 
float a,b; 
a=111111.111; 
b=333333.333; 
printf("a+b= %f\n",a+b); 
}
运行结果为: 
444444.453125 
很明显,只有前7位是有效数字,给出6位小数。实数输出时不要认为输出的数字都是
准确的。
【例3.4】 输出双精度实数,观察有效位数。 
main( ) 
{ 
double a,b; 
a=1111111111111.111111111; 
b=3333333333333.333333333; 
printf("a+b= %f\n",a+b); 
}
运行结果为: 
4444444444444.444340 
很明显,只有前16位是有效数字,给出6位小数。最后3位小数超过了16位,无意义。
(2)输出八进制整数和十六进制整数。
【例3.5】 已知十进制整数,输出与其对应的八进制整数和十六进制整数。 
void main( ) 
{ 
int a=180; 
printf("八进制= %o\n",a); 
printf("十六进制= %x\n",a); 
printf("十六进制= %X\n",a); 
}
运行结果为: 
八进制= 264 
十六进制= b4 
十六进制= B6 
(3)输出一个字符。
使用格式%c输出。一个字符既可以作为字符输出,也可以作为整数(该字符对应的

46 C 语言程序设计
ASCII码)输出;反之,一个整数,只要它在0~255范围内,也可以将该整数作为ASCII码
的相应字符输出。
【例3.6】 输出字符。 
void main( ) 
{ 
char c='M'; 
int j=81; 
printf("%c,%d\n",c,c); 
printf("%c,%d \n",j,j); 
}
运行结果为: 
M,77 
Q,81 
(4)输出字符串。
【例3.7】 使用格式%s输出字符串。 
main( ) 
{ 
printf("%s%s\n","CHINA"," IS A GREAT COUNTRY!"); 
}
运行结果为: 
CHINA IS A GREAT COUNTRY! 
输出的字符串不包括引号。
3.printf函数的附加格式说明字符
在格式说明中,%和格式字符之间可以带有附加格式说明字符(又称修饰符),如表3.2 
所示。
表3.2 printf函数的附加格式说明字符(修饰符) 
字 符说 明
字母l 用于长整型整数,可加在类型字符d、i、o、x、u前面;用于双精度实数,可加在f、e、
g前面
m(代表一个正整数) 数据输出的最小宽度,右对齐方式,空出的左端补空格
n(代表一个正整数) 对实数,输出n位小数;对字符串,从左端截取n个字符输出
- 输出的数字或字符在域内向左靠
# 加在格式字符o、x前面,使系统输出八进制的前缀0和十六进制的前缀0x 
数字0 输出数值时在左面不使用的空位置补0 
对于附加格式说明字符(修饰符),重点说明下面几种情况。
(1)%md表示输出十进制整数的最小宽度为m 位,即输出字段的宽度至少占m 列,右
对齐,数据少于m 位则在左端补空格(或0)使之达到m 位;数据超过m 位则m 不起作用, 
按数据的实际位数输出。数据前要补0,则在m 前面加个0。
例如:若k=18,p=31689,则 
printf("%6d",k); 输出结果为: ||||18 
printf("%06d",k); 输出结果为: 000018

第3 章 顺序结构程序设计 47 
printf("%4d",p); 输出结果为: 31689 
类似地还有%mc、%mo、%mu、%ms等。
(2)字母l。在输出d、i、o、u、x等整型数据时,在前面加上字母l表示输出的是一个长
整型数据。
【例3.8】 输出数据时,修饰符———字母l的应用。 
main( ) 
{ 
long a=245978; 
printf("a=%ld,a=%d\n",a,a); 
}
运行结果为: 
a=245978,a=-16166 
前一个数据是正确的,后一个数据是错误的。因为245978已经超出整型数据的范围- 
32767~32768,必须要用长整型数据格式输出。
(3)%m.nf表示输出数据为小数形式,m 为总宽度(包括小数点),n为小数部分的位
数。小数长度不够则补0,小数部分超过n位,则n+1位向n位四舍五入;整个数据小于m 
位左补空格,超过m 位,则m 不起作用,按数据的实际位数输出。
例如:若x=123.45,y=123.456,z=-123.45,则 
printf("x=%10.4f",x); 输出结果为:x=||123.4500 
printf("y=%10.2f",y); 输出结果为:y=||||123.46 
printf("z=%4.2f",z); 输出结果为:z=-123.45 
(4)%m.ns表示输出数据为字符串形式,m 是总宽度,但当实际位数超过时,多余者将
被删除,n表示只取字符串中左端的n位,n<m 时,左边补空格;n>m 时,m 自动取n值, 
保证n位字段的正常输出。例如: 
printf("%7.3s", "12345" ); 输 出结果为:||||123 
printf("%5.7s", "12345678"); 输 出结果为:1234567 
不过,在程序中用得较多的形式还是%s,使用该格式输出时,按实际内容输出。例如: 
printf("%s", "12345"); 输 出结果为12345 
printf("%s", "12345678"); 输 出结果为12345678 
(5)-表示左对齐格式,若没有则为右对齐格式。例如: 
printf("%-5d", 12); 输出结果为12 ||| 
printf("%-5s", "1243"); 输出结果为1243 | 
printf("%-7.3s", "12345" ); 输 出 结果为123 |||| 
printf("%-5.7s", "12345678"); 输出结果为1234567 
printf("%-5.7s", "123456"); 输 出结果为123456 | 
printf("%-10.2f",123.456); 输 出结果为123.46 |||| 
4.使用printf函数时的注意事项
(1)在格式控制字符串中,格式说明与输出表列中的参数个数应该相同。若格式说明
的个数少于参数的个数,多余的参数不予输出;若格式说明的个数多于参数的个数,则多余
的参数将输出不定值或零值。
(2)在格式控制字符串中,格式说明与输出表列中的参数从左到右在类型上必须一一
匹配。若不匹配将导致数据不能正确输出(输出数据的类型由格式说明确定),这时,系统并

48 C 语言程序设计
不报错。例如: 
【例3.9】 格式说明与输出表列不匹配的情况。 
main( ) 
{ 
char c='M'; 
int j=81; 
printf("%d\n",c); 
printf("%c \n",j); 
}
运行结果为: 
77 
Q(
3)在格式控制字符串中,可以包含任意的合法字符(包括转义字符),这些字符在输出
时将原样输出。
(4)若想输出字符“%”,则需在格式说明中用连续的两个“%”表示,例如: 
printf("%f%% \n",25.3); 
输出结果为: 
25.300000% 
3.3.2 格式输入函数———scanf函数
1.scanf函数的一般格式 
scanf函数的一般格式如下: 
scanf(格式控制字符串,地址表列); 
例如: 
scanf("%d,%f",&a, &b); 
说明: 
(1)格式控制字符串必须用双引号括起来。格式控制字符串由两类不同的内容组成。
第一类是普通字符。输入数据时,必须在对应位置上原样输入。
第二类是格式说明。scanf函数中的格式说明与printf函数类似,由“%”和格式字符组
成(也可以在其中间加入修饰符),如%d等。它指定要输入的数据的格式。
(2)地址表列是接收输入数据的变量的存储单元地址,或字符串的首地址。变量的地
址由“&”加变量名组成,如上例中的&a和&b,scanf函数的作用是将从键盘输入的数据存
入变量地址中。地址表列中地址的个数超过一个时用逗号分隔。地址表列和格式说明在个
数和类型上要一一匹配。
如: 
scanf("%d,%f",&a, &b); 
若从键盘输入: 
7,12.345 ↙

第3 章 顺序结构程序设计 49 
则7存入变量a的地址中(a得到7),12.345存入变量b的地址中(b得到12.345)。
2.scanf函数的格式字符和附加格式说明字符
scanf函数中的格式字符如表3.3所示。scanf函数的附加格式说明字符(修饰符)如
表3.4所示。
表3.3 scanf函数的格式字符
输入类型格式字符说 明
整型数据
d,i 输入带符号的十进制整数
o 输入无符号的八进制整数(可以带前缀0,也可以不带) 
u 输入无符号的十进制整数
x,X 输入无符号的十六进制整数(可以带前缀0x或0X,也可以不带),大小写作
用相同
字符型数据
c 输入一个字符
s 输入一个字符串,将字符串送到一个字符数组中。输入时以非空白字符开
始,以第一个空白字符结束。字符串以串结束标志\' 0'作为其最后一个字符
实型数据f 以小数形式或指数形式输入实数
e,E,g,G 与f作用相同,e与f、g可以互相替换(大小写作用相同) 
表3.4 scanf函数的附加格式说明字符(修饰符) 
字 符说 明
字母l 用于输入长整型数据(可用%ld,%lo,%lx,%lu)以及double型数据(可用% 
lf或%le) 
h 用于输入短整型数据(可用%hd,%ho,%hx) 
域宽m(代表一个正整数) 指定输入数据所占的宽度(列数) 
* 表示本输入项在读入后不赋给相应的变量 
说明: 
(1)若多个格式控制字符中无分隔符,从键盘输入数据(不是字符型数据)时,可用隐含
分隔符隔开。隐含分隔符有空格(一个或多个)、Enter键、Tab键。
例如,假设a、b、c为整型变量,要使它们分别得到值30、40、50。使用以下输入语句: 
scanf("%d%d%d",&a,&b,&c); 
键盘输入数据的格式: 
① 30 |40 |50 ↙ 
② 30 ↙ 
40 |50 ↙ 
③ 30 |40 ↙ 
50 ↙ 
④ 30(按Tab 键)40 ↙ 
50 ↙ 
⑤ 30 ↙ 
40 ↙ 
50 ↙ 
注意:其中空格“|”可以是一个也可以是若干个。

50 C 语言程序设计
(2)若在格式控制字符串中有其他字符(如逗号等),则在输入数据时,要在相应位置原
样输入这些字符。如: 
① scanf("%d,%d",&a,&b); 
可从键盘输入: 
30,40 ↙ 
注意:“,”必须在对应位置上原样输入;若不输入“,”则是错误的。
如输入: 
10 |20 ↙或10:20 ↙ 
均是错误的。
② 若有以下输入语句: 
scanf("a=%d,b=%d",&a,&b); 
在输入时必须为: 
a=10,b=20 ↙ 
而输入: 
10 |20 ↙或a=10 |b=20 ↙ 
是错误的。
(3)关于输入字符型数据时,转义字符和隐含分隔符的使用问题。
① 字符和字符之间不能使用转义字符和隐含分隔符。在用“%c”输入多个字符型数据
时,数据之间不可以使用转义字符和隐含分隔符(空格、Enter键、Tab键),因为系统此时会
把转义字符、隐含分隔符作为有效字符型数据送给字符变量。例如: 
scanf("%c%c",&x,&y); 
使x得到a,y得到b。若输入: 
ab ↙ 
则正确。
若输入: 
a |b ↙ 
则不正确。此时,x得到a,y得到|。
② 数字和字符之间能不能使用转义字符和隐含分隔符,要视情况而定。例如: 
scanf("%d%c",&x,&y); 
使x得到68,y得到b。若输入: 
68b ↙ 
则正确。若输入: 
68 |b ↙ 
则不正确。此时,x得到68,y得到|。 
scanf("%c%d ",&x,&y); 
使x得到b,y得到68。输入:

第3 章 顺序结构程序设计 51 
b |68 ↙或b68 ↙ 
都正确。为保险起见,字符和字符之间、数字和字符之间不要使用转义字符和隐含分
隔符。
(4)如果指定了输入数据的宽度,系统将自动按此宽度截取所需的数据。例如: 
scanf("%3d%3d%2d",&a,&b,&c); 
输入: 
12345678 ↙ 
则123赋给a,456赋给b,78赋给c。
但是,在输入实数时,不能规定小数位。例如: 
scanf("%10.4f",&p); 
是错误的。
(5)一个格式说明中出现“*”时,表示读入该类型的数据不赋给某个变量(相当于跳过
该数据)。
【例3.10】 “*”的使用。 
main( ) 
{ 
int a,b; 
scanf("%3d%*2d%4d",&a,&b); 
printf("a=%d,b=%d\n",a,b); 
}
输入: 
987654321 ↙ 
则变量a得到987,65跳过,变量b得到4321。运行结果为: 
a=987, b=4321 
(6)输入数据时,遇到下述情况认为该数据结束。
① 遇到空格、Enter键或Tab键。
② 按指定的宽度结束,例如%4d,只取4列。
③ 遇到非法输入。例如: 
scanf("%d%c%f",&a,&b,&c); 
若输入: 
5678p345o.79 ↙ (o 是字母,不是数字0) 
则变量a得到5678,变量b得到字符p,变量c得到345(没有得到应该得到的3450.79)。
字母o在这里非法。
(7)若有确定数据的最大位数的修饰符m,当输入数据的位数少于m 时,程序等待输
入,直到满足要求或遇到非法字符为止;当输入数据位数多于m 时,多余数据将作为下一个
数据读入其他变量。例如: 
scanf("%3d%3d",&a,&b); 
输入: 
视频

52 C 语言程序设计 
12345 ↙ (输入数据的位数少于3+3 位) 
则变量a得到123,变量b得到45(遇Enter键)。若输入 
1 |2345 ↙ 
则变量a得到1(遇空格)而不是12、102或123,变量b得到234。例如: 
scanf("%3d%3d%3d",&a,&b,&c); 
输入: 
1234 |6789 ↙ (输入数据1234 的位数4 多于a 要求的3 位) 
则变量a得到123,后面的4读入a的后一变量b(b读入4后遇空格结束),变量b得到4, 
变量c得到678。
(8)当一行内输入的数据个数小于格式控制字符串的个数时,光标会出现在下一行,等
待用户继续输入。C语言允许在一行内输入的数据个数大于格式控制字符串的个数,这时
会把多余的数据留给后面的scanf函数使用。
(9)输入长整型数据和double型数据时,在%和格式字符之间加l,如%ld、%lf等。
3.使用scanf函数时的注意事项
(1)scanf函数中地址表列使用的是变量的地址而不是变量名。例如scanf("%d%d", 
x,y);是错误的。
(2)scanf函数没有计算功能,输入的数据只能是常量,而不能是表达式。
(3)在格式控制字符串中不要使用转义字符,如\n。
(4)格式说明和地址表列在类型上要一一匹配。若不匹配,系统并不报错,但不可能得
到正确的结果。
(5)格式说明和地址表列在个数上要相同。若格式说明的个数少于地址表列的个数, 
则scanf函数结束输入,多余的地址表列并没得到新数据;若格式说明的个数多于地址表列
的个数,则scanf函数等待输入。
3.3.3 字符输出函数———putchar函数
putchar函数的作用是向屏幕(显示器)输出一个字符。
putchar函数的一般调用格式如下: 
putchar(c); 
它将c输出到屏幕上。c既可以是常量,也可以是字符变量、整型变量或表达式。
【例3.11】 字符数据的输出。 
# include <stdio.h> 
main( ) 
{ 
char a='y', b='e', c='s'; /*字符变量*/ 
putchar(a); putchar(b); putchar(c); 
putchar('\n'); / * 转 义 字符,换行*/ 
putchar('P'); /* 字 符 常量*/ 
putchar(81); / * 整型常量,ASCII 码值为81 的字符Q */ 
putchar('\333'); / * AS CI I 码用八进制表示为333(十进制表示为219)的字符■*/

第3 章 顺序结构程序设计 53 
putchar('K'+2); / * 表 达 式,即输出字符M */ 
}
运行结果为: 
yes 
PQ■M 
3.3.4 字符输入函数———getchar函数
getchar函数的作用是接收从键盘输入的一个字符。当程序执行到getchar函数时,将
等待用户从键盘输入一个字符。
其一般调用格式如下: 
getchar( ); 
注意:括号()中间无参数。getchar函数只接收一个字符。
【例3.12】 从键盘输入一个字符,把它存入字符型变量x中,并输出。 
# include <stdio.h> 
main( ) 
{ 
char x; 
x=getchar( ); 
putchar(x); /*用putchar 函数输出*/ 
}
输入: 
y ↙ 
运行结果为: 
y
说明:getchar函数得到的字符可以赋给一个字符变量或整型变量,也可以不赋给任何
变量,而作为表达式的一部分。
【例3.13】 从键盘输入一个字符,不赋给任何变量。 
# include <stdio.h> 
main( ) 
{ 
putchar(getchar( )); 
}
输入: 
9 ↙ 
运行结果为: 
9
在这里,9是一个字符。
语句putchar(getchar());用printf("%c",getchar());代替也可以。

54 C 语言程序设计
3.4 C语句概述
C语言的语句分为5类,分别为复合语句、空语句、表达式语句、控制语句和函数调用
语句。下
面重点介绍复合语句、空语句和表达式语句,简单介绍控制语句和函数调用语句。控
制语句和函数调用语句在后续章节再重点学习。
3.4.1 复合语句
C语言把由一对花括号({})括起来的一组语句称为复合语句。
例如: 
{ 
t=a; 
a=b; 
b=t; 
}
一个复合语句在语法上可以看作一个整体。在程序中,凡是单个语句能够出现的地方
复合语句都可以出现。
复合语句作为一个整体又可以出现在其他复合语句的内部,并且复合语句中也可以定
义变量,但所定义的变量仅在本复合语句中有效。
例如: 
main( ) 
{ char c; 
… 
{ double x; 
… 
{ double y; 
scanf("%lf",&y); 
printf("x+y=%lf",x+y); 
} 
… 
} 
… 
} 
3.4.2 空语句
在程序设计中,特别是在复杂程序的调试过程中,往往需要加一个或若干个空语句来表
示存在某个或某些语句。
所谓空语句,就是一个不含其他内容而仅含分号的语句。
例如:

第3 章 顺序结构程序设计 55 
main( ) 
{ 
… 
; /*空语句*/ 
… }
注意:对空语句的使用一定要慎重,因为随意加分号极易导致逻辑上的错误。
3.4.3 表达式语句
任何一个表达式的后面加上一个分号就构成了表达式语句。例如: 
x+y 
是表达式,而 
x+y; 
是表达式语句。
最典型的是由一个赋值表达式加分号构成一个赋值语句。例如: 
x=80 
是赋值表达式,而 
x=80; 
是赋值语句。
3.4.4 控制语句
用来实现一定的控制功能的语句称为控制语句。C语言中有9种控制语句: 
(1)if…else… 条件语句。
(2)switch 多分支选择语句。
(3)while… 循环语句。
(4)do…while 循环语句。
(5)for… 循环语句。
(6)break 中止执行switch或循环语句。
(7)goto 转向语句。
(8)continue 结束本次循环语句。
(9)return 函数返回语句。
3.4.5 函数调用语句
由函数调用加分号构成了函数调用语句。例如: 
printf("请输入a,b 的值:"); 
add(a,b); 
是两个函数调用语句(函数调用语句将在第7章中大量使用)。

56 C 语言程序设计
科学素质拓展———安常处顺,顺应自然,随遇而安,不负韶华。
《庄子.养生主》:“适来,夫子时也;适去,夫子顺也。安时而处顺,哀乐不能入也。”意思
是一个人偶然来到世间,这是他顺时而生;偶然离去了,这是他顺时而死。安于时运而顺应
自然,一切哀乐之情就不能进入心怀。后以“安常处顺”指习惯于正常生活,处于顺利境
遇中。
“顺应自然,随遇而安”是中国传统文化中的一种重要的生活哲学观念。它强调人们应
该顺应自然,不去过分计较,能够安然自在地应对生活的各种变化。从儒家、道家和马克思
主义哲学等不同的角度来解读“随遇而安”,可以更深刻地理解其内涵。
在儒家看来,“顺应自然,随遇而安”需要人们根据自己的生活情境和社会环境,选择适
合自己的生活方式,同时也要认真对待自己的人生,积极面对生活中的各种挑战。
在道家看来,“顺应自然,随遇而安”需要人们通过修炼自己的内心,放下执着和烦恼,平
静地面对生活中的各种变化和困难。同时,也需要人们以宽广的心态来看待生活,顺应自
然,不为外物所动,始终保持内心的平静与安宁。
在马克思主义哲学看来,“顺应自然,随遇而安”需要人们以开放的心态面对生活,接纳
事物的发展和环境的变化,不断地修正自己的观念和行为方式,实现自身的成长和进化,从
困境和挫折中寻找启示和智慧,从而更好地理解万事万物的内在规律,遵循事物发展的规
律,到相应的时间就做相应的事情。比如小时候是读书识字的年龄,就要认真读书,错过识
字的年龄,以后难以弥补,正所谓少壮不努力,老大徒伤悲。
希望我们每个人就如丰子恺在《不宠无惊过一生》中写道的:“不乱于心,不困于情。不
畏将来,不念过往。如此,安好。”以梦为马,享受生命馈赠,不负韶华。
3.5 应用举例
【例3.14】 编写一个程序,分别输入一个八进制、十进制和十六进制数,将这3个数相
加,以十进制的形式输出。
分析: 
(1)首先定义变量,用来保存输入的数据及运算结果。
(2)输入八进制、十进制和十六进制数。
(3)对数据求和。
(4)输出结果(数据输出)。
程序如下: 
main( ) 
{ 
int a,b,c,d; 
printf("请输入八进制、十进制、十六进制数据: \n"); 
scanf("%o%d%x",&a,&b,&c); 
d=a+b+c; 
printf("输入的三个数据为: %o %d %x \n",a,b,c); 
printf("对应的十进制数为:%d %d %d \n",a,b,c); /*以十进制输出这3 个数*/ 
printf("sum=%d \n",d); 
}

第3 章 顺序结构程序设计 57 
程序执行: 
请输入八进制、十进制、十六进制数据: 
12 |34 |7a ↙ //键盘输入数据
输入的三个数据为: 12 34 7a 
对应的十进制数为: 10 34 122 
sum=164 
【例3.15】 从键盘输入一个大写字母,把它转换为小写字母后输出。
分析: 
(1)数据输入、输出类似于例3.14。
(2)本题的关键是清楚字母大小写的转换规则。查附录A 可知,小写字母在大写字母
之后,且同一个字母的ASCII码值小写比大写大32,若大写字母用变量c1表示,小写字母
用变量c2表示,则c2=c1+32,这是一种方式;另一种方式是c2=c1+a' ' -'A',请考虑这是
为什么? 
程序如下: 
main( ) 
{ 
char c1,c2; 
scanf("%c",&c1); 
c2=c1+'a'-'A'; /*'a'-'A'为同一个小写字母和大写字母的ASCII 码之差*/ 
printf("Upper=%c,Lower=%c",c1,c2); 
}
运行结果为: 
D ↙ 
Upper=D,Lower=d 
请思考:如果从键盘输入一小写字母,把它转换为大写字母后输出,程序如何编写? 
【例3.16】 输入三角形的三条边长,求三角形的面积(假设输入的三条边能构成三角形)。
分析: 
(1)首先要明确三角形面积的计算公式。从数学中知道,假设三条边用a、b、c表示,三
角形面积的计算公式如下: 
s=(a+b+c)/2 
area= s(s-a)(s-b)(s-c) 
(2)为a、b、c输入值(假设输入的三条边能构成三角形)。
(3)C语言开平方可以使用系统提供的数学函数sqrt。
程序如下: 
# include <stdio.h> 
# include <math.h> 
void main( ) 
{ 
float a,b,c,s,area; 
scanf("%f,%f,%f",&a,&b,&c); 
s=(a+b+c)/2; 
area=sqrt(s*(s-a)*(s-b)*(s-c)); 
printf("a= %6.2f,b=%6.2f,c=%6.2f\n",a,b,c); 
printf("area=%6.2f\n",area); 
视频

58 C 语言程序设计
}
运行结果为: 
3,4,6 ↙ //假如输入的数据为3、4、6 
a= 3.00, b= 4.00, c= 6.00 
area= 5.33 
sqrt函数的原型在math.h头文件中。因此必须在程序头部使用文件包含命令# 
include"math.h"或#include<math.h>。
请思考:area=sqrt(s*(s-a)*(s-b)*(s-c));可以写成area=sqrt(s(s-a)(s-b) 
(s-c));吗? 
习 题 3 
一、选择题 
1.下述哪一个不是结构化程序基本结构? ( ) 
A.顺序B.选择C.循环D.嵌套
2.组成C语句的一个必不可少的符号是( )。
A.逗号B.引号C.冒号D.分号
3.下述是C语言中有关变量定义的几个说法,正确的是( )。
A.变量可以不定义直接使用
B.一个说明语句只能定义一个变量
C.几个不同类型的变量可在同一语句中定义
D.变量可以在定义时进行初始化
4.以下所列语句中,合法的语句是( )。
A.a=1,b=2 B.++a; C.a=a+1=5 D.y=int(a); 
5.与x* = y+z等价的赋值表达式是( )。
A.x= y+z B.x= x* y+z 
B.x= x* (y+z) D.x= x+ y*z 
6.使用语句scanf("x=%f,y=%f",&x,&y);输入变量x、y的值(□代表空格),正确
的输入是( )。
A.1.25,2.4 B.1.25□2.4 
C.x=1.25,y=2.4 D.x=1.25□y=2.4 
7.已知字母A 的ASCII码是65,以下程序的执行结果是( )。 
#include<stdio.h> 
main() 
{ 
char c1='A',C2='Y'; 
printf("%d,%d\n",c1,c2); 
} 
A.A,Y B.65,65 C.65,90 D.65,89 
二、给出运行结果题
1.给出下列程序段的输出结果。

第3 章 顺序结构程序设计 59 
(1) int a=1, b=2; 
printf("a=%d%%,b=%d\n",a,b); 
(2) int a=-1; 
printf("%d,%u",a,a); 
(3) int x=10; 
printf("x=%d,x=%#x\n",x,x); 
(4) int d=389; 
printf("*%-07d*\n",d); 
(5) double y=123.456789; 
printf("y=%8.6f,y=%8.2f,y=%14.8f,y=%14.8lf\n",y,y,y,y); 
2.分析下列程序,并给出运行结果。 
(1) main( ) 
{ 
int a,b; 
float f; 
scanf("%d,%d",&a,&b); /*输入1 和2*/ 
f=a/b; 
printf("F=%f",f); 
} 
(2) main() 
{ 
int sum,pad; 
sum=pad=5; 
pad=sum++; 
pad++; 
++pad; 
printf("%d\n",pad); 
} 
三、改错题
指出下面程序中的错误并改正。 
main( ) 
{ 
float b; 
char c; 
int d; 
scanf("%c%d%c%f",a,b,c,d); 
printf("a+b+c+d=%f\n", a+b+c+d); 
}
四、编程题
1.编写程序,输入实数a和b的值,求其和并输出。
2.编写程序,将输入的小写字母转换为大写字母后输出。
3.编写程序,输入某个学生3门功课的成绩,求出它们的和及平均成绩。要求平均成
绩保留小数点后1位。
4.输入圆的半径,求圆的面积和周长。
5.输入两个正整数,求它们相除所得的商,商的整数部分、小数部分及余数。例如21 
除以2,其商为10.5,商的整数部分为10,小数部分为0.5,余数为1。

第4章

选择结构程序设
计


从选择的权利谈起——
— 

人类无时无刻不在做出选择,就像当下这一刻,你可以选择认真学习,也可以选择游玩

潇洒。但是,无论你做出什么选择,你都需要为这个选择而造成的结果负责。今天的选择是

因,才造成了明天的结果。比如,你选择认真听讲,好好学习,才有以后取得好成绩的果;同

样,如果你游玩偷懒,以后就可能不及格甚至无法毕业。有时候,即使是父母逼迫你做出某

个选择,比如你想学文科,可是父母逼迫你学理科,其结果也是你在承受,因为这是你的

人生。

俗话说:“ 所有偷过的懒,都会变成打脸的巴掌。”如果不想挨巴掌,就要学会如何做出
更好的选择并为自己的人生负责任。

第3章讲解了顺序结构的程序,只能按照语句先后顺序处理问题,虽然能解决计算、输
出等问题,但不能做判断再选择。在很多情况下,需要根据不同的前提条件做出选择,即从
给定的两种或多种操作选择其一,这就要求程序本身具有完备的条件判断和选择能力。从
流程图角度看,选择结构是一种双分支或多分支结构,从主观角度看,它是一种能执行选择
权利的结构。因此选择结构也称分支结构。

在程序设计中,选择结构根据给定的条件判断选择哪一条分支,从而执行相应的语句。
在使用选择结构时,关键在于进行条件判断,要用条件表达式来描述条件,条件表达式可以
是关系运算表达式或者逻辑运算表达式。本章介绍选择结构程序设计,主要内容包括关系
运算、逻辑运算、if语句、switch语句等。

4.关系运算符和关系表达式
1 

关系运算也叫比较运算。在程序中经常用来比较两个量的大小关系,以决定程序下一
步的走向。比较两个量的运算符称为关系运算符。

1.关系运算符及其优先顺序
4.1 
C语言中的关系运算符共有6种,它们是: