第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种,它们是: