第3章 顺序结构程序设计 C语句是C语言程序的重要组成元素。C语言的程序是由一条条语句组成的,程序 执行时按照一定的顺序逐条完成其中的语句,直到程序结束。本章将学习以下内容。 ● C语句以及分类 ● 格式化输入/输出函数 ● 字符型数据输入/输出函数 ● 顺序结构程序设计 3.1 C语句概述 学一学 C语言的语句可以分为以下5类。 (1)表达式语句 表达式语句指由一个表达式加上一个分号构成的语句,例如: x=5; //赋值语句 i++; //自增1 语句,i 值加1,等价于i=i+1; a+b; //加法运算语句,但计算结果未保留,无实际意义 执行表达式语句就是计算表达式的值。 (2)函数调用语句 函数调用语句指由一次函数调用加上一个分号构成的语句,例如: printf("Hello World!\n"); //调用printf 函数输出字符串 m=max(x, y); //调用max 函数计算x 和y 的较大值,并赋值给m (3)空语句 空语句指只由一个分号构成的语句。 ; 空语句什么都不做,一般用作循环语句中的循环体。 48 C 语言程序设计 (4)控制语句 控制语句用于控制程序的流程。C语言有9种控制语句,可以分为3类。 ● 条件判断语句:if语句、switch语句。 ● 循环执行语句:dowhile语句、while语句、for语句。 ● 转向语句:break语句、goto语句、continue语句、return语句。 这些控制语句的具体用法将在后续章节中进行详细介绍。 (5)复合语句 用括号{}括起来的多个语句组成的语句块被称为复合语句。在程序中把复合语句看 成一个整体,例如: { scanf("%d", &n); //输入一个整数n s=s+n; //累加至s 中 } 复合语句可以出现在任何单个语句出现的位置,在单个语句位置需要放置由多个语 句才能表达的功能时,需要使用复合语句。复合语句广泛用于选择结构语句与循环结构 语句中。 3.2 格式化输入输出函数 本节主要介绍格式化输出函数printf和格式化输入函数scanf。 3.2.1 格式化输出函数printf printf函数为格式化输出函数,其功能是按用户指定的格式把指定的数据输出到显 示器屏幕上。 1.函数调用的形式 学一学 函数调用的一般格式为 printf(格式控制字符串, 输出表列); 其中,格式控制字符串用于指定输出格式,通常是双引号括起来的字符串常量。格式 控制字符串可由格式字符串和非格式字符串两部分组成。格式字符串是以%开头的字符 串,在%后面跟有各种格式字符,以说明输出数据的类型、宽度、小数位数等。非格式字符 串在输出时原样输出,只起提示作用。输出表列列出了各个输出项,要求格式字符串和各 输出项在数量和类型上一一对应。 第3 章 顺序结构程序设计 49 试一试 例3-1 输出两个整型变量的值。 #include "stdio.h" void main() { int a=65, b=97; printf("整型格式输出: a=%d,b=%d\n", a, b); } 程序运行结果如下。 整型格式输出: a=65,b=97 2.格式控制字符串 学一学 格式字符串的一般形式为 %[标志][输出最小宽度][.精度][长度]类型 其中,方括号中的项为可选项。各项具体含义如下。 (1)类型 类型字符用于表示输出数据的类型,类型格式符和含义见表3-1。 表3-1 格式字符串中的类型及其含义 数据类型类型格式符含 义 整型数据 %d 以十进制形式输出带符号整数 %o 以八进制形式输出带符号整数 %x、%X 以十六进制形式输出带符号整数 %u 以十进制形式输出无符号整数 实型数据 %f 以十进制小数形式输出单、双精度实数 %e、%E 以指数形式输出单、双精度实数 %g、%G 选%f、%e中较短的格式输出单、双精度实数 字符型数据%c 输出单个字符 %s 输出字符串 说明 一个整数如果在0~127中,也可以用%c按字符形式输出,在输出前,系统会将该整 数作为ASCII码转换成相应的字符,如printf("%c",65);将输出字符A。%f用来以十 进制小数形式输出单、双精度实数,默认整数部分全部输出,小数部分输出6位。输出的 50 C 语言程序设计 数字并非全部是有效数字,单精度实数的有效位数一般为7位,双精度实数的有效位数一 般为16位。%e用来以指数形式输出单、双精度实数,默认数值按标准化指数形式输出,即小 数点前必须有且只有一个非零数字,保留6位小数,指数部分占5列(如1.234568e+002, 其中e占1列,指数符号+或-占1列,指数占3列)。例如: int i=65; float f=12.3456789; printf("%d %c %o %x", i, i, i, i); printf("%c\n", 65); printf("%f\n", f); printf("%%e\n", f); 将输出: 65 A 101 41 (ACSII 码值等于65 的字符为A) 12.345679 (默认输出6 位小数,7 位有效数字为12.34567) 1.234568e+001 (默认输出6 位小数,最后一位四舍五入) (2)输出最小宽度(m) 用十进制整数来表示数据输出的最小位数(包括正负号、小数点)。若实际位数多于 定义的宽度,则按实际位数输出;若实际位数少于指定的宽度,则补以空格。例如: printf("%5f\n", 12.3456789); //指定宽度5,实际宽度9(6 位小数+小数点+2 位整数) printf("%15f\n", 12.3456789); //指定宽度15,实际宽度9(6 位小数+小数点+2 位整数) printf("%8s\n", "Congratulation"); //指定宽度8,实际宽度14 printf("%18s\n", "Congratulation"); //指定宽度18,实际宽度14 将输出: 12.345679 12.345679 (前补6 个空格) Congratulation Congratulation (前补4 个空格) (3).精度(n) 精度格式符以“.”开头,后跟十进制整数表示精度。如果输出数值,则表示小数的位 数;如果输出的是字符,则表示输出字符的个数;若实际位数大于所定义的精度数,则截取 超过的部分(对小数位数四舍五入截去)。例如: printf("%.2f\n", 12.3456); //指定输出小数位数2,实际小数位数4 printf("%.6f\n", 12.3456); //指定输出小数位数6,实际小数位数4 printf("%.5s\n", "Congratulation"); //指定输出字符个数5,实际字符个数14 printf("%.15s\n", "Congratulation"); //指定输出字符个数15,实际字符个数14 将输出: 12.35 第3 章 顺序结构程序设计 51 12.345678 Congr Congratulation (4)标志 标志字符为-、+、#、空格,其含义见表3-2。 表3-2 格式字符串中的标志及其含义 标志符含 义 - 结果左对齐,右边填空格,默认右对齐,左边填空格 + 输出符号(正号或负号) # 对o类,在输出时加前缀0;对x类,在输出时加前缀0x;对e、f、g类,当结果有小数时 才给出小数点;对c、s、d、u类无影响 空格输出值为正时冠以空格,为负时冠以负号 例如: int i=65, n=-65; float f=123.456; printf("%8.2f\n", f); printf("%-8.2f\n", f); printf("%+d %+d\n", i, n); printf("%d %o %x %#o %#x\n", i, i, i, i, i); printf("%d\n", i); //d 前有1 空格 printf("%d\n", n); //d 前有1 空格 将输出: 123.46 (前补2 个空格) 123.46 (后补2 个空格) +65-65 65 101 41 0101 0x41 65 (前冠1 个空格) -65 (5)长度 长度格式符为h、l两种。其中h表示按短整型输出,l表示按长整型输出,l在e、f、g 前,指定输出精度为double。 3.2.2 格式化输入函数scanf scanf函数为格式化输入函数,是按照用户指定的格式从键盘上把数据输入(接收)到 指定的变量中。 52 C 语言程序设计 1.函数调用的形式 学一学 函数调用的一般格式为 scanf(格式控制字符串, 地址列表); 其中,格式控制字符串的作用与printf函数相同;地址列表中给出变量的地址,多个 地址以逗号“,”隔开,地址一般由地址运算符& 后跟变量名组成。 试一试 例3-2 利用scanf函数输入两个整数,然后输出它们之和。 #include "stdio.h" void main() { int a, b; printf("请输入两个整数: \n"); scanf("%d%d", &a, &b); printf("%d+%d=%d\n", a, b, a+b); } 程序运行结果如下。 请输入两个整数: 2 3 2+3=5 说明 在scanf语句的格式串中由于没有非格式字符在"%d%d"之间作输入时的间隔,因 此在输入时要用一个以上的空格或回车键作为每两个输入数据之间的间隔。 2.格式字符串 学一学 格式字符串的一般形式为 %[*][输入数据宽度][长度]类型 其中,有方括号的项为可选项,各项的含义如下。 (1)类型 类型字符用于表示输入数据的类型,类型格式符和含义见表3-3。 (2)“*”符号 该符号用于表示输入项读入后不赋予相应的变量,即跳过该输入值。例如scanf("% d%*d%d",&a,&b);,当输入为123时,把1赋予a,2被跳过,3赋予b。 第3 章 顺序结构程序设计 53 表3-3 格式字符串中类型格式符及其含义 数据类型类型格式符含 义 整型数据 %d 输入十进制整数 %o 输入八进制整数 %x 输入十六进制整数 %u 输入无符号十进制整数 实型数据%f或%e 输入实型数(用小数形式或指数形式) 字符型数据%c 输入单个字符 %s 输入字符串 (3)输入数据宽度 用十进制整数指定输入数据的宽度(即字符数)。例如scanf("%5d",&a);,若输入 12345678,则只把12345赋予变量a,其余部分被截去。 (4)长度 长度格式符为h、l两种。其中h表示输入短整型数据,l表示输入长整型数据(%ld) 或双精度浮点数(%lf)。 说明 ①scanf函数没有精度控制,如scanf("%5.2f",&a);是不合法的。 ②scanf中要求给出变量地址,若给出非地址变量名,则会出错。 ③ 在输入多个数值数据时,若格式控制串中没有非格式字符作为输入数据之间的间 隔,则可用空格、Tab键或回车键作间隔。输入数据时,遇到以下情况认为该数据输入已 结束:空格、回车键、Tab键等;满宽度(如%3d,满3位数字);非法字符输入。 ④ 在输入字符数据时,若格式控制串中没有非格式字符,则认为输入的所有字符均 为有效字符。例如scanf("%c%c%c",&a,&b,&c);,若输入def,则把'd'赋予a,' '赋 予b,e' '赋予c。只有当输入为def时,才能把d' '赋予a,e' '赋予b,f' '赋予c。 ⑤ 如果在格式控制字符串中加入空格作为间隔,如scanf("%c%c%c",&a,&b, &c);则输入时各数据之间可加空格。 ⑥ 如果格式控制串中有非格式字符,则输入时也要原样输入该非格式字符。例如 scanf("%d,%d,%d",&a,&b,&c);。其中,用非格式符“,”作间隔符,故输入时应输 入5,6,7。 ⑦ 输入字符串时,遇到空格即认为数据接收结束,详见7.3节。 试一试 例3-3 scanf函数输入数据举例。 .................................... 程序代码.................................... #include "stdio.h" void main() 54 C 语言程序设计 { int i1,i2,i3,i4; char a, b, c; float f; double d; printf("输入数值:"); scanf("%d%o%x%u%f%lf", &i1, &i2, &i3, &i4, &f, &d); getchar(); //接收回车键 printf("输出:"); printf("%d,%d,%d,%d,%f,%lf\n",i1,i2,i3,i4,f,d); printf("再输入数值:"); scanf("%d,%o,%x,%u,%f,%lf", &i1, &i2, &i3, &i4, &f, &d); getchar(); //接收回车键 printf("输出:"); printf("%d,%d,%d,%d,%f,%lf\n",i1,i2,i3,i4,f,d); printf("输入字符:"); scanf("%c%c%c", &a, &b, &c); getchar(); //接收回车键 printf("输出:"); printf("%c,%c,%c\n",a,b,c); printf("再输入字符:"); scanf("%c%c%c", &a, &b, &c); getchar(); //接收回车键 printf("输出:"); printf("%c,%c,%c\n",a,b,c); } 程序运行结果如下。 输入数值:65 101 41 65 1.23 4.56 输出:65,65,65,65,1.230000,4.560000 再输入数值:65,101,41,54,1.23,4.56 输出:65,65,65,54,1.230000,4.560000 输入字符:abc 输出:a,b,c 再输入字符:a b c 输出:a, ,b 3.3 字符数据的输入输出 本节主要介绍字符数据的输入函数getchar与输出函数putchar。 第3 章 顺序结构程序设计 55 3.3.1 putchar函数 学一学 putchar函数的作用是向终端(屏幕)输出一个字符,其一般形式为 putchar(字符变量、字符常量或整型值); 试一试 例3-4 输出单个字符。 .................................... 程序代码.................................... #include "stdio.h" void main() { char c='A'; int n=66; putchar(c); putchar(n); putchar('C'); } 程序运行结果如下。 ABC 3.3.2 getchar函数 学一学 getchar函数的作用是从键盘输入一个字符,该函数没有参数,返回值就是从输入设 备得到的字符,其一般形式为 getchar(); 试一试 例3-5 输入单个字符然后输出。 .................................... 程序代码.................................... #include "stdio.h" void main() { char c; c=getchar(); 56 C 语言程序设计 putchar(c); } 程序运行结果如下。 AA 说明 getchar函数只能接收一个字符,该函数得到的字符可以赋给一个字符变量或整型变 量,也可以不赋给任何变量而作为表达式的一部分,如上例中字符'A'的输入输出可以用 下面一行代码实现。 putchar(getchar()); 3.4 顺序结构程序设计 顺序结构是最简单的一种程序结构,语句按程序书写的顺序执行。C语言程序一般 由变量定义、数据输入、计算处理、结果输出四个部分组成。 下面介绍几个顺序结构程序设计的例子。 试一试 例3-6 输入三角形的三边长,求三角形的面积。 .................................... 解题思路.................................... 分析:三角形的面积计算公式为 area= s(s-a)(s-b)(s-c) 其中,s=(a+b+c)/2,具体解题步骤如下。 ① 变量定义:定义变量area、s、a、b、c。 ② 数据输入:调用scanf函数输入三角形的三边长a、b、c。 ③ 计算处理:计算s值并代入面积计算公式计算aera。 ④ 结果输出:调用printf函数输出计算结果。 .................................... 程序代码.................................... #include "stdio.h" #include "math.h" void main() { float a,b,c,s,area; printf("请输入三角形的三个边的边长: \n"); scanf("%f%f%f",&a,&b,&c); 第3 章 顺序结构程序设计 57 s=(float)(a+b+c) / 2; area=(float)sqrt(s*(s-a)*(s-b)*(s-c)); printf("三角形的面积为%5.2f\n",area); } 程序运行结果如下。 请输入三角形的三个边的边长: 3 4 5 三角形的面积为6.00 程序注解 由于要调用数学函数库中的函数,因此必须用#include将数学函数库的头文件 math.h包含进程序。 例3-7 求一元二次方程ax2+bx+c=0的根,a、b、c 由键盘输入,设b2-4ac>0。 .................................... 解题思路.................................... 分析:b2-4ac>0时,一元二次方程有两个不相等的实根,分别为 x1 = -b+ b2 -4ac 2a , x2 = -b- b2 -4ac 2a 具体解题步骤如下。 ① 变量定义:定义变量a、b、c、disc、x1、x2。 ② 数据输入:调用scanf函数输入三个系数a、b、c。 ③ 计算处理:计算disc值并代入实根计算公式计算x1和x2。 ④ 结果输出:调用printf函数输出计算结果。 .................................... 程序代码.................................... #include "stdio.h" #include "math.h" void main() { float a,b,c,disc,x1,x2; printf("请输入求一元二次方程的系数: \n"); scanf("%f%f%f",&a,&b,&c); disc=b*b-4*a*c; x1=(float)(-b+sqrt(disc))/(2*a); x2=(float)(-b-sqrt(disc))/(2*a); printf("方程的根为: x1=%.2f, x2=%.2f\n",x1,x2); } 程序运行结果如下。 请输入求一元二次方程的系数: 2 3 1 方程的根为: x1=-0.50, x2=-1.00 58 C 语言程序设计 3.5 典型题解 试一试 例3-8 整数的拆分。从键盘输入任意一个三位正整数x,输出这个数的百位、十位 和个位数字。 .................................... 解题思路.................................... 分析:个位数字通过x%10获得,x/10为截掉个位数字后变成的两位数,为此,原整 数的十位数字等于x/10%10(也可通过x%100/10获得),百位数字通过x/100获得。 .................................... 程序代码.................................... #include "stdio.h" void main() { int x, g, s, b; printf(请输入一个三位整数: "); scanf("%d",&x); g=x%10; s=x/10%10; //或s=x%100/10 b=x/100; printf("%d 的个位数字为%d,十位数字为%d,百位数字为%d\n",x,g,s,b); } 程序运行结果如下。 请输入一个三位整数: 123 123 的个位数字为3,十位数字为2,百位数字为1 3.6 本章小结 本章主要介绍了数据的格式化输入与输出、字符型数据的输入与输出,以及顺序结构 程序设计的一般步骤。 习 题 3 一、选择题 1.若有定义charc;doubled;,程序运行时输入12<回车>,则能把字符1输入给 第3 章 顺序结构程序设计 59 变量c、数值2输入给变量d的输入语句是( )。 A.scanf("%d%lf",&c,&d); B.scanf("%c%lf",&c,&d); C.scanf("%c%f",&c,&d); D.scanf("%d%f",&c,&d); 2.若有程序段 char c; double d; scanf("%lf%c", &d, &c); 如果想把2.3输入给变量d,字符e' '输入给变量c,则程序运行时正确的输入是( )。 A.2.3e B.2.3e C.2.3e' ' D.2.3e' ' 3.以下叙述中正确的是( )。 A.在scanf函数中的格式控制字符串是为了输入数据用的,不会输出到屏幕上 B.在使用scanf函数输入整数或实数时,输入数据之间只能用空格来分隔 C.在printf函数中,各个输出项只能是变量 D.使用printf函数无法输出百分号% 4.设有定义doublex=2.12;,以下不能完整输出变量x值的语句是( )。 A.printf("x=%5.0f\n",x); B.printf("x=%f\n",x); C.printf("x=%1f\n",x); D.printf("x=%0.5f\n",x); 5.设有语句printf("%2d\n",2010);,则以下叙述正确的是( )。 A.程序运行时输出2010 B.程序运行时输出20 C.程序运行时输出10 D.指定的输出宽度不够,编译出错 6.若有定义inta=1234,b=-5678;,用语句printf("%+-6d%+-6d",a,b); 输出,则以下正确的输出结果是( )。 A.+1234-5678(中间有1个空格,最后有1个空格) B. +1234-5678(最前面有1个空格,中间有1个空格) C.+-1234+-5678(最前面和最后均无空格) D.1234 -5678(中间有2个空格,最后有1个空格) 7.有以下程序: #include "stdio.h" void main() { char a, b, c, d; scanf("%c%c", &a, &b); c=getchar(); d=getchar(); printf("%c%c%c%c\n", a, b,c, d); } 当执行程序时,按下列方式输入数据(从第1列开始,代表回车,注意:回车也 是一个字符): 60 C 语言程序设计 12 34 则输出结果是( )。 A.12 B.12 C.1234 D.12 34 3 8.以下不能输出小写字母a的选项是( )。 A.printf("%c\n","a"); B.printf("%c\n",'A'+32); C.putchar(97); D.putchar(a' '); 9.设有定义语句doublex=123.456;,则语句printf("%6.2f,%3.0f\n",x,x);的输 出结果是( )。 A.123.46,123 B.123.45,123 C.123.46,123.0 D.123.45,123. 10.若有定义doublea;chard;floatb;,若想把1.2输入给变量a,字符'k'输入给变 量d,3.4输入给变量b,程序运行时键盘输入: 1.2 k 3.4<回车> 则以下正确的读入语句是( )。 A.scanf("%1f%c%f",&a,&d,&b); B.scanf("%lf %c %f",&a,&d,&b); C.scanf("%f %c %f",&a,&d,&b); D.scanf("%f%c%f",&a,&d,&b); 11.语句printf("%s\n","\\' 101\x42\\");的输出结果是( )。 A.'AB\ B.\a' b C.\\' 101\x42\\ D .a' b\ 二、填空题 1.以下程序借助变量t,把a、b的值进行交换,请填空。 #include "stdio.h" void main() { int a, b, t; scanf("%d%d", ); t=a; ; b=t; printf("a=%d, b=%d\n", a, b); } 2.以下语句的输出结果为。 float x=1234.5678; double y=1234.5678; printf("x=%5.3f, y=%7.5e\n", x, y); 3.若想通过下面的输入语句使a=5.0,b=4,c=3,则输入数据的形式是。 第3 章 顺序结构程序设计 61 int b, c; float a; scanf("%f,%d,c=%d", &a, &b, &c); 三、阅读程序写结果 1.下列程序的运行结果是。 #include "stdio.h" void main() { int k=33; printf("%d,%o,%x\n", k, k, k); } 2.有以下程序 #include "stdio.h" void main() { int x, y; scanf("%3d%*3c%3d", &x, &y); printf("%d %d\n", x, y); } 当程序运行时,如果输入11222333<回车>,则输出结果是。 3.下列程序的运行结果是。 #include "stdio.h" void main() { double x=3.14159; printf("%f\n", (int)(x*1000+0.5)/(double)1000); } 4.下列程序的运行结果是。 #include "stdio.h" void main() { int a=1, b=2; float c=1.0; printf("%0.2f,%0.2f\n", a/b, c/b); } 四、编写程序题 1.编写程序,从键盘输入梯形的上下底边长度和高,计算梯形的面积。 2.输入一个华氏温度,要求输出摄氏温度。公式为 5 c= 9(F-32) 输出要有文字说明,取2位小数。 3. 某项自行车比赛以秒计时(只保留整数)。试编写一个程序,从键盘输入一个选手 的比赛成绩,然后转化成“x分x秒”的表示形式。 4. 编写一个程序,根据本金a、存款年数 n 和年利率 p 计算到期利息i。利息的计算 公式为in -。 =a×(1+p) a 62 C 语言程序设计