4.1 C语句概述
4.2 程序的三种基本结构
4.3 赋值语句
4.4 数据输入输出的概念及在C语言中的实现
4.5 字符数据的输入输出
4.6 格式输入与输出
4.7 顺序结构程序设计举例习题第 4章 最简单的 c程序设计 — 顺序程序设计在上一章介绍了程序中用到的一些基本要素
(常量、变量、运算符、表达式等 ),它们是构成程序的基本成分。在第 1章中已经介绍了几个简单的 c程序。本章将介绍为编写简单的程序所必需的一些内容。
4.1 C语句概述和其他高级语言一样,c语言的语句用来向计算机系统发出操作指令。一个语句经编译后产生若干条机器指令。一个实际的程序应当包含若干语句。应当指出,
c语句都是用来完成一定操作任务的。声明部分的内容不应称为语句。如,int a;不是一个 c语句,它不产生机器操作,而只是对变量的定义。从第 1章已知,
一个函数包含声明部分和执行部分,执行部分即由语句组成。 c程序结构可以用图 4.1表示。即一个 c程序可以由若干个源程序文件 (分别进行编译的文件模块 )组成,一个源文件可以由若干个函数和预处理命令以及全局变量声明部分组成 (关于“全局变量”见第 7章,
“预编译命令”见第 8章 ),一个函数由数据定义部分和执行语句组成。
图 4.1
在第 2章中已经说明,程序应该包括数据描述 (由声明部分来实现 )和数据操作 (由语句来实现 )。数据描述主要定义数据结构 (用数据类型表示 )和数据初值。数据操作的任务是对已提供的数据进行加工。
C语句可以分为以下 5类:
(1) 控制语句,完成一定的控制功能。 c只有 9种控制语句,它们是:
① if()~ else~ (条件语句 )
② for()~ (循环语句 )
③ w hile()~ (循环语句 )
④ do~w hile() (循环语句 )
⑤ continue (结束本次循环语句 )
⑥ break (中止执行 switch或循环语句 )
⑦ sw itch (多分支选择语句 )
⑧ goto (转向语句 )
⑨ return (从函数返回语句 )
上面 9种语句中的括号 ()表示其中是一个条件,~
表示内嵌的语句。例如:,if()~ else~”的具体语句可以写成:
if(x> y) z=x; else z=y;
(2) 函数调用语句。由一次函数调用加一个分号构成一个语句,例如,printf("this is a c statem
ent,");
(3) 表达式语句。 由一个表达式构成一个语句,
最典型的是,由赋值表达式构成一个赋值语句。
a=3
是一个赋值表达式,而
a=3;
是一个赋值语句。可以看到一个表达式的最后加一个分号就成了一个语句。一个语句必须在最后出现分号,分号是语句中不可缺少的一部分 (而不像 pascal语言那样,分号只是语句间的分隔符号 )。
例如:
i=i+1 (是表达式,不是语句 )
i=i+1; (是语句 )
任何表达式都可以加上分号而成为语句,例如 i++;
是一语句,作用是使 i值加 1。又如 x+y;也是一个语句,作用是完成 x+y的操作,它是合法的,
但是并不把 x+y的和赋给另一变量,所以它并无实际意义。
表达式能构成语句是 c语言的一个重要特色。其实
“函数调用语句”也是属于表达式语句,因为函数调用 (如 sin(x))也属于表达式的一种。只是为了便于理解和使用,我们把“函数调用语句”和
“表达式语句”分开来说明。由于 c程序中大多数语句是表达式语句 (包括函数调用语句 ),所以有人把 c语言称作“表达式语言”。
(4) 空语句。下面是一个空语句:;
即只有一个分号的语句,它什么也不做。有时用来做被转向点,或循环语句中的循环体 (循环体是空语句,表示循环体什么也不做 )。
(5) 可以用 {}把一些语句括起来成为复合语句,
又称分程序。如下面是一个复合语句。
{ z=x+y;
t=z/100;
printf("%f",t);

注意:复合语句中最后一个语句中最后的分号不能忽略不写 (这是和 pascal不同的 )。
C语言允许一行写几个语句,也允许一个语句拆开写在几行上,书写格式无固定要求 (fortran、
cobol有严格要求 )。
4.2 程序的三种基本结构为了提高程序设计的质量和效率,现在普遍采用结构化程序设计方法。结构化程序由若干个基本结构组成。每一个基本结构可以包含 一个或若干个语句。有三种基本结构,
(1) 顺序结构,见图 4.2。先执行 a操作,再执行 b操作,
两者是顺序执行的关系。图中 (b)是 ns结构化流程图 (下同 )。
图 4.2 图 4.3
(2) 选择结构,见图 4.3。 p代表一个条件,当 p条件成立 (或称为“真” )时执行 a,否则执行 b。注意,只能执行 a或 b之一。两条路径汇合在一起然后出口。
(3) 循环结构,有两种循环结构,
① 当型循环结构,见图 4.4。当 p条件成立 (“真” )时,
反复执行 a操作。直到 p为“假”时才停止循环。
② 直到型循环结构,见图 4.5。先执行 a操作,再判断 p
是否为“假”,若 p为“假”,再执行 a,如此反复,直到 p为“真”为止。
图 4.4 图 4.5
由选择结构可以派生出另一种基本结构,多分支选择结构,见图 4.6。
根据 k的值 (k1,k2,…,kn) 不同而决定执行 a1,a2,…,an
之一。
已经证明,由以上基本结构组成的程序能处理任何复杂的问题。上面图 4.2~图 4.7中方框中的
a,b,a1,…,an 等可以是一个简单的语句,也可以又是一个基本结构。例如,图 4.7是一个顺序结构,它由两个操作顺序组成。虚线框内是一个当型循环结构,可以用,b”表示,因此图 4.7就可以理解为图
4.2(a)所示的顺序结构。
图 4.6 图 4.7
关于三种基本结构的特征以及结构化程序设计方法,
读者可能已在学习其他高级语言程序设计时学习过,在此不再重复。只是应当强调说明,在今后的程序设计中应当采用结构化程序设计方法。在本章中,我们将介绍几种最基本的语句,以及用它们构成顺序结构的程序。在第 4、第 5章介绍选择结构和循环结构的程序设计。
4.3 赋值语句前已介绍,赋值语句是由赋值表达式加上一个分号构成。由于赋值语句应用十分普遍,所以专门再讨论一下。
C语言的赋值语句具有其他高级语言的赋值语句的一切特点和功能。但也应当注意到它们的不同:
(1) C语言中的赋值号,=”是一个运算符,在其他大多数语言中赋值号不是运算符。
(2) 关于赋值表达式与赋值语句的概念,其他多数高级语言没有“赋值表达式”一概念。作为赋值表达式可以包括在其他表达式之中,例如:
if((a=b)> 0)t=a;
按语法规定 if后面的 ( )内是一个条件,例如可以是:,if(x> 0)…” 。现在在 x的位置上换上一个赋值表达式,a=b”,其作用是:先进行赋值运算
(将 b的值赋给 a),然后判断 a是否大于 0,如大于 0,
执行 t=a。在 if语句中的,a=b”不是赋值语句而是赋值表达式,这样写是合法的。如果写成
if((a=b; )> 0)t=a;就错了。在 if的条件中不能包含赋值语句。由此可以看到,c把赋值语句和赋值表达式区别开来,增加了表达式的种类,使表达式的应用几乎“无孔不入”,能实现其他语言中难以实现的功能,
4.4 数据输入输出的概念及在 C语言中的实现
(1) 所谓输入输出是以计算机主机为主体而言的。从计算机向外部输出设备 (如显示屏、打印机、磁盘等 )输出数据称为“输出”,从外部向输入设备
(如键盘、磁盘、光盘、扫描仪等 )输入数据称为
“输入”。
(2) C语言本身不提供输入输出语句,输入和输出操作是由函数来实现的。在 c标准函数库中提供了一些输入输出函数,例如,printf函数和 scanf函数。
读者在使用它们时,千万不要误认为它们是 C语言提供的“输入输出语句”。 printf和 scanf不是 C
语言的关键字,而只是函数的名字。实际上完全可以不用 printf和 scanf这两个名字,而另外编两个输入输出函数,用其他的函数名。 C提供的函数以库的形式存放在系统中,它们不是 c语言文本中的组成部分。
在第 1章中曾介绍,不把输入输出作为 C语言提供的语句的目的是使 C语言编译系统简单,因为将语句翻译成二进制的指令是在编译阶段完成的,没有输入输出语句就可以避免在编译阶段处理与硬件有关的问题,可以使编译系统简化,而且通用性强,可移植性好,对各种型号的计算机都适用,便于在各种计算机上实现。各种版本的 C语言函数库是各计算机厂商 (或软件开发公司 )针对某一类型计算机的情况编写的,并且已编译成目标文件 (.obj文件 )。它们在连接阶段与由源程序 经编译而得到的目标文件相连接,
生成一个可执行的目标程序。如果在源程序中有
printf函数,在编译时并不把它翻译成目标指令,而是在执行阶段中调用已被连接的函数库中的 printf函数。由于 c编译系统与 c函数库是分别进行设计的,
因此不同的计算机系统所提供函数的数量、名字和功能是不完全相同的。不过,有些通用的函数
(如 printf和 scanf等 ),各种计算机系统都提供,
成为各种计算机系统的标准函数。 c语言函数库中有一批“标准输入输出函数”,它是以标准的输入输出设备 (一般为终端设备 )为输入输出对象的。其中有,putchar(输出字符 ),getchar(输入字符 ),printf(格式输出 ),scanf(格式输入 ),
puts(输出字符串 ),gets(输入字符串 )。在本章中介绍前面 4个最基本的输入输出函数。
(3) 在使用 c语言库函数时,要用预编译命令“#
include”将有关的“头文件” 包括到用户源文件中。
在头文件中包含了与用到的函数有关的信息。例如使用标准输入输出库函数时,要用到,stdio.h”文件。
文件后缀,h” 是 head的缩写,#include命令都是放在程序的开头,因此这类文件被称为“头文件” 。
在调用标准输入输出库函数时,文件开头应有以下预编译命令:
#include <studio.h>

#include "studio.h"
studio,h是 standard input & output的缩写,它包含了与标准 i/o库有关的变量定义和宏定义 (有关预编译命令见第 7章 )。考虑到 printf和 scanf函数使用频繁,
系统允许在使用这两个函数时可不加 #include命令。
4.5 字符数据的输入输出我们先介绍 c标准 i/o函数库中最简单的、也是最容易理解的字符输入输出函数 putchar()和 getchar(),再介绍格式输入输出函数 printf()和 scanf()函数。
4.5.1 putchar函数 (字符输出函数 )
putchar函数的作用是向终端输出一个字符:例如
putchar(c);它输出字符变量 c的值。 c可以是字符型变量或整型变量。
例 4.1输出单个字符。
#include <stduio,h>
main()
{ char a,b,c;
a='b'; b='o'; c='y';
putchar(a); putchar(b); putchar(c);

运行结果:
boy
也可以输出控制字符,如 putchar(?\n?)输出一个换行符,使输出的当前位置移到下一行的开头。如果将例 4.1程序最后一行改为
putchar(a);putchar(?\n?);putchar(b);putchar(?\n?);
putchar(c); putchar(?\n?);
则输出结果为:
b
o
y
也可以输出其他转义字符,如:
putchar('\101')(输出字符 'a')
putchar('\'') (输出单引号字符 ')
putchar('\015') (输出回车,不换行,使输出的当前位置移到本行开头 )
4.5.2 getchar函数 (字符输入函数 )
此函数的作用是从终端 (或系统隐含指定的输入设备 )输入一个字符。 getchar函数没有参数,其一般形式为 getchar()
函数的值就是从输入设备得到的字符。例如:
例 4.2输入单个字符
#include <stdio,h>
main()
{ charc;
c=getchar();
putchar(c);

在运行时,如果从键盘输入字符‘ a?并按回车键,就会在屏幕上看到输出的字符‘ a?。 a (输入 'a'后,按“回车”
键,字符才送到内存 )
a (输出变量 c的值 'a')
请注意,getchar()只能接收一个字符。 getchar函数得到的字符可以赋给一个字符变量或整型变量,也可以不赋给任何变量,作为表达式的一部分。例如,例 4.2第 4,5行可以用下面一行代替:
putchar(getchar());
因为 getchar()的值为‘ a?,因此 putchar函数输出‘ a?。也可以用 printf函数输出:
printf(”%c",getchar());请不要忘记,如果在一个函数中
(今为 main函数 )要调用 getchar函数,应该在该函数的前面 (或本文件开头 )加上“包含命令”
#include <stdio,h>
4.6.1 printf函数 (格式输出函数 )
在前面各章节中已用到 printf函数,它的作用是向终端 (或系统隐含指定的输出设备 )输出若干个任意类型的数据 (putchar只能输出字符,而且只能是一个字符,而 printf可以输出多个数据,且为任意类型 )。
1,printf函数的一般格式为 printf(格式控制,输出表列 )
如,printf("%d,%c\n",i,c)
括弧内包括两部分:
4.6 格式输入与输出
(1),格式控制”是用双引号括起来的字符串,也称
“转换控制字符串”,它包括两种信息:
① 格式说明,由,%”和格式字符组成,如 %d,
%f等。它的作用是将输出的数据转换为指定的格式输出。格式说明总是由,%”字符开始的。
② 普通字符,即需要原样输出的字符。例如上面
printf函数中双引号内的逗号、空格和换行符。
(2),输出表列”是需要输出的一些数据,可以是表达式。
2,格式字符对不同类型的数据用不同的格式字符。常用的有以下几种格式字符:
(1) d格式符。用来输出十进制整数。有以下几种用法:
① %d,按整型数据的实际长度输出。
② %md,m为指定的输出字段的宽度。如果数据的位数小于 m,则左端补以空格,若大于m,
则按实际位数输出。如
printf("%4d,%4d",a,b);
若 a=123,b=12345,则输出结果为
123,12345
③ %ld,输出长整型数据。如
longa=135790;
printf("%ld",a);
如果用 %d输出,就会发生错误,因为整型数据的范围为 -
32768~ 32767。对 long型数据应当用 %ld格式输出。对长整型数据也可以指定字段宽度,如将上面 printf函数中的
,%ld”改为,%8ld”,则输出为:
135790
8列一个 int型数据可以用 %d或 %ld格式输出。
(2) o格式符,以八进制数形式输出整数。由于是将内存单元中的各位的值 (0或 1)按八进制形式输出,因此输出的数值不带符号,即将符号位也一起作为八进制数的一部分输出。例如:
int a=-1;
printf("%d,%o",a,a);
-1在内存单元中的存放形式 (以补码形式存放 )如下:
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
输出为
-1,177777
不会输出带负号的八进制整数。对长整数 (long型 )
可以用,%lo”格式输出。同样可以指定字段宽度,
如 printf(“%8o”,a) 输出为 177777。
(3) x格式符,以十六进制数形式输出整数。同样不会出现负的十六进制数。例如:
int a=-1;
printf("%x,%o,%d",a,a,a);
输出结果为
ffff,177777,-1
同样可以用,%lx”输出长整型数,也可以指定输出字段的宽度,如,%12x”。
(4) u格式符,用来输出 unsigned型数据,即无符号数,以十进制形式输出。
一个有符号整数 (int型 )也可以用 %u格式输出;反之,一个 unsigned型数据也可以用 %d格式输出。
按相互赋值的规则处理 (见第 2章 2.9节 )。 unsigned
型数据也可用 %o或 %x格式输出。
例 4.3无符号数据的输出。
main()
{ unsigned int a=65535;
int b=-2;
printf("a=%d,%o,%x,%u\n",a,a,a,a);
printf("b=%d,%o,%x,%u\n",b,b,b,
b);

运行结果为:
a=-1,177777,ffff,65535
b=-2,177776,fffe,65534
请读者自己分析。
(5) c格式符,用来输出一个字符。如:
char c='a';
printf("%c",c);
输出字符‘ a?,请注意:,%c”中的 c是格式符,逗号右边的 c是变量名,不要搞混。
一个整数,只要它的值在 0~ 255范围内,也可以用字符形式输出,在输出前,系统会将该整数作为
ascii码转换成相应的字符;反之,一个字符数据也可以用整数形式输出。例 4.4字符数据的输出。
main()
{ char c='a';
int i=97;
printf("%c,%d\n",c,c);
printf("%c,%d\n",i,i);

运行结果为:
a,97
a,97
也可以指定输出字数宽度,如果有
printf("%3c",c)
则输出:,a”,即 c变量输出占 3列,前 2列补空格。
(6) s格式符,用来输出一个字符串。有几种用法:
① %s,例如,printf("%s","china")
输出,china”字符串 (不包括双引号 )。
② %ms,输出的字符串占m列,如字符串本身长度大于 m,则突破m的限制,将字符串全部输出。
若串长小于 m,则左补空格。
③ %-ms,如果串长小于m,则在m列范围内,
字符串向左靠,右补空格。
④ %m,ns,输出占m列,但只取字符串中左端
n个字符。这 n个字符输出在m列的右侧,左补空格。
⑤ %-m,ns,其中m,n含义同上,n个字符输出在m列范围的左侧,右补空格。如果 n>m,则
m自动取 n值,即保证 n个字符正常输出。
例 4.5字符串的输出。
main()

printf("%3s,%7.2s,%.4s,%-5.3s\n",
"china","china","china","china")

输出如下:
china,ch,chin,chi
其中第 3个输出项,格式说明为,%.4s”,即只指定了 n,没指定m,自动使m =n=4,故占 4列。
(7) f格式符,用来输出实数 (包括单、双精度 ),以小数形式输出。有以下几种用法:
① %f,不指定字段宽度,由系统自动指定,使整数部分全部如数输出,并输出 6位小数。应当注意,并非全部数字都是有效数字。单精度实数的有效位数一般为 7位。
例 4.6输出实数时的有效位数。
main()
{ float x,y;
x=111111,111; y=222222,222;
printf("%f",x+y);

运行结果为
333333,328125
显然,只有前 7位数字是有效数字。千万不要以为凡是打印出来的数字都是准确的。
双精度数也可用 %f格式输出,它的有效位数一般为 16
位,给出小数 6位。
例 4.7输出双精度数时的有效位数。
main()
{ double x,y;
x=1111111111111.111111111;
y=2222222222222.222222222;
printf("%f",x+y);

输出结果为
3333333333333.333010
可以看到最后 3位小数 (超过 16位 )是无意义的。
② %m,nf 指定输出的数据共占m列,其中有
n位小数。如果数值长度小于m,则左端补空格。
③ %-m,nf与 %m,nf 基本相同,只是使输出的数值向左端靠,右端补空格。
例 4.8输出实数时指定小数位数。
main()
{
float f=123.456;
printf("%f %10f %10.2f %.2f %-
10.2f\n",f,f,f,f,f);

输出结果如下:
123.456001 123.456001 123.46 123.46 123.46
f的值应为 123.456,但输出为 123.455994,这是由于实数在内存中的存储误差引起的。
(8) e格式符,以指数形式输出实数。可用以下形式:
① %e不指定输出数据所占的宽度和数字部分的小数位数,有的 c编译系统自动指定给出 6位小数,指数部分占 5位 (如 e+002),其中,e”占 1位,指数符号占 1位,指数占 3位。数值按规范化指数形式输出
(即小数点前必须有而且只有 1位非零数字 )。例如
printf("%e",123,456);
输出,1,234560e+002。
6列 5列输出的实数共占 13列宽度。 (注,不同系统的规定略有不同 )
② %m.ne和 %-m.ne。 m,n和,-”字符含义与前相同。此处 n指拟输出的数据的小数部分 (又称尾数 )
的小数位数。若 f=123,456,则:
printf("%e %10e %10.2e %.2e %-10.2e",f,f,
f,f,f);
输出如下:
1.234560e+002 1.234560e+002 1.23e+002 1.23e+002 1.23e+002
13列 13列 10列 9列 10列第 2个输出项按 %10e输出,即只指定了m =10,未指定 n,凡未指定 n,自动使 n=6,整个数据长 13
列,超过给定的 10列,乃突破 10列的限制,按实际长度输出。第 3个数据共占 10列,小数部分占 2
列。第 4个数据按,%,2e”格式输出,只指定
n=2,未指定m,自动使m等于数据应占的长度,
今为 9列。第 5个数据应占 10列,数值只有 9列,由于是,%-10,2e”,数值向左靠,右补一个空格。
(注,有的 c系统的输出格式与此略有不同 )
(9) g格式符,用来输出实数,它根据数值的大小,自动选 f
格式或 e格式 (选择输出时占宽度较小的一种 ),且不输出无意义的零。例如,若 f=123,468,则 printf(“%f %e
%g”,f,f,f);
输出如下:
123.468000 1.234680e+002 123.468
10列 13列 10列用 %f格式输出占 10列,用 %e格式输出占 13列,用 %g格式时,自动从上面两种格式中选择短者 (今以 %f格式为短 ),
故占 10列,且按 %f格式用小数形式输出,最后 3个小数位
,0”为无意义的 0,不输出,因此输出 123.468,然后右补
3个空格。 %g格式用得较少。
在使用 printf函数时,还有几点要说明:
(1) 除了 x,e,g外,其他格式字符必须用小写字母,
如 %d不能写成 %d。
(2) 可以在 printf函数中的“格式控制”字符串内包含第 2章 2.5节 2.5.1段中的“转义字符”,如,\n”、
,\t”、,\b”、,\r”、,\f”、,\377”等。
(3) 上面介绍的 d,o,x,u,c,s,f,e,g等字符,
如用在,%”后面就作为格式符号。一个格式说明以,%”开头,以上述 9个格式字符之一为结束,
中间可以插入附加格式字符 (也称修饰符 )。例如:
第一个格式说明为,%c”而不包括其后的 f,第二个格式说明为,%f”,不包括其后的 s,第三个格式说明为 %s。其他的字符为原样输出的普通字符。
(4) 如果想输出字符,%”,则应该在“格式控制”
字符串中用连续两个 %表示,如,
printf("%f%%",1,0/3);
输出,0,333333%
4.6.2 scanf函数 (格式输入函数 )
在第 1章中已初步接触到了 scanf函数,在本节中再作详细介绍。
1,一般形式
scanf(格式控制,地址表列 )
“格式控制”的含义同 printf函数;“地址表列”是由若干个地址组成的表列,可以是变量的地址,
或字符串的首地址。
例 4.9用 scanf函数输入数据。
m ain()
{ int a,b,c;
scanf(“%d%d%d”,
&a,&b,&c);
printf("%d,%d,
%d\n",a,b,c);

图 4.8
运行时按以下方式输入 a,b,c的值:
3 4 5 (输入 a,b,c的值 )
3,4,5 (输出 a,b,c的值 )
&a,&b,&c中的,&”是“地址运算符”,&a指 a
在内存中的地址。上面 scanf函数的作用是:按照
a,b,c在内存的地址将 a,b,c的值存进去。见图 4.8。变量 a,b,c的地址是在 编译连接阶段分配的。
,%d%d%d”表示按十进制整数形式输入数据。输入数据时,在两个数据之间以一个或多个空格间隔,也可以用回车键、跳格键 tab。下面输入均为合法:
① 3 4 5
② 3
4 5
③ 3(按 tab键 )4
5
用,%d%d%d”格式输入数据时,不能用逗号作两个数据间的分隔符,如下面输入不合法:
3,4,5
2,格式说明和 printf函数中的格式说明相似,以 %开始,以一个格式字符结束,中间可以插入附加的字符。
说明:
(1) 对 unsigned型变量所需的数据,可以用 %u,%d
或 %o,%x格式输入。
(2) 可以指定输入数据所占列数,系统自动按它截取所需数据。如,scanf("%3d%3d",&a,&b);
输入,123456
系统自动将 123赋给 a,456赋给 b。此方法也可用于字符型,scanf("%3c",&ch);
如果从键盘连续输入 3个字符 abc,由于 ch只能容纳一个字符,系统就把第一个字符‘ a?赋给 ch。
(3) 如果在 %后有一个,*”附加说明符,表示跳过它指定的列数。例如,scanf("%2d
%*3d %2d",&a,&b);如果输入如下信息:
12 345 67
将 12赋给 a,%*3d表示读入 3位整数但不赋给任何变量。然后再读入 2位整数 67赋给 b。
也就是说第 2个数据,345”被跳过。在利用现成的一批数据时,有时不需要其中某些数据,可用此法“跳过”它们。
(4) 输入数据时不能规定精度,例如,
scanf("%7,2f",&a);
是不合法的,不能企图用这样的 scanf函数并输入以下数据而使 a的值为 12345,67。 1234567
3,使用 scanf函数时应注意的问题
(1) scanf函数中的“格式控制”后面应当是变量地址,
而不应是变量名。例如,
如果 a,b为整型变量,则
scanf("%d,%d",a,b);
是不对的,应将,a,b”改为,&a,&b”。这是 c语言与其他高级语言不同之处。许多初学者常在此出错。
(2) 如果在“格式控制”字符串中除了格式说明以外还有其他字符,则在输入数据时应输入与这些字符相同的字符。例如
scanf("%d,%d",&a,&b);
输入时应用如下形式:
3,4
注意 3后面是逗号,它与 scanf函数中的“格式控制”
中的逗号对应。如果输入时不用逗号而用空格或其他字符是不对的:
3 4 (不对 )
3:4 (不对 )
如果是
scanf("%d %d",&a,&b);
输入时两个数据间应空 2个或更多的空格字符。如:
10 34 或 10 34
如果是
scanf("%d∶ %d∶ %d",&h,&m,&s);
输入应该用以下形式:
12∶ 23∶ 36
如果是
scanf("a=%d,b=%d,c=%d",&a,&b,&c);
输入应为以下形式:
a=12,b=24,c=36
这种形式为了使用户输入数据时添加必要的信息以帮助理解,不易发生输入数据的错误。
(3) 在用,%c”格式输入字符时,空格字符和“转义字符”都作为有效字符输入:
scanf("%c%c%c",&c1,&c2,&c3);
如输入 a b c
字符‘ a?送给 c1,字符‘ ’送给 c2,字符‘ b?送给
c3,因为 %c只要求读入一个字符,后面不需要用空格作为两个字符的间隔,因此‘ ’作为下一个字符送给 c2。
(4) 在输入数据时,遇以下情况时该数据认为结束。
① 遇空格,或按“回车”或“跳格” (tab)键。
② 按指定的宽度结束,如,%3d”,只取 3列。
③ 遇非法输入。
如 scanf("%d%c%f",&a,&b,&c);
若输入
1234 a 1230.26
↓ ↓ ↓
a b c
第一个数据对应 %d格式在输入 1234之后遇字母 a,
因此认为数值 1234后已没有数字了,第一个数据到此结束,把 1234送给变量 a。字符‘ a?送给变量 b,
由于 %c只要求输入一个字符,因此输入字符 a之后不需要加空格,后面的数值应送给变量 c。如果由于疏忽把本来应为 1230.26错打成 123o.26,由于 123
后面出现字母‘ o?,就认为该数值数据到此结束,
将 123送给 c。
C语言的格式输入输出的规定比较繁琐,用得不对就得不到预期的结果,而输入输出又是最基本的操作,
几乎每一个程序都包含输入输出,不少编程人员由于掌握不好这方面的知识而浪费了大量调试程序的时间。因此我们做了比较仔细的介绍,以便在编程时有所遵循。但是,在学习本书时不必花许多精力去死抠每一个细节,重点掌握最常用的一些规则即可。
其他部分可在需要时随时查阅。这部分的内容建议自学和上机,教师不必在课堂上一一细讲。应当通过编写和调试程序来逐步深入而自然地掌握输入输出的应用。
4.7 顺序结构程序设计举例下面介绍几个顺序程序设计的例子。
例 4.10输入三角形的三边长,求三角形面积。
为简单起见,设输入的三边长 a,b,c能构成三角形。
从数学知识已知求三角形面积的公式为其中 s=(a+b+c)/2
据此编写程序如下:
# include <m ath,h>
m ain()

float a,b,c,s,area;
scanf("%f,%f,%f",&a,&b,&c);
s=1,0/2 (a+b+c);
area=sq rt(s (s-a) (s-b) (s-c));
printf("a=%7.2f,b=%7.2f,c =%7.2f,s
=%7.2f\n",a,b,c,s);
printf("area=%7,2f\n",area);

程序中第 7行中 sqrt()是求平方根的函数。由于要调用数学函数库中的函数,必须在程序的开头加一条 #include命令,把头文件,math.h”
包含到程序中来。请注意,以后凡在程序中要用到数学函数库中的函数,都应当“包含” math.h头文件。
运行情况如下:
3,4,6
a= 3.00,b= 4.00,c= 6.00,s= 6.50
area= 5,33
例 4.11从键盘输入一个大写字母,要求改用小写字母输出。前面已介绍过大小写字母间转换的方法,
根据此思路编出下面的程序。
#include <stdio.h>
main()

char cl,c2;
cl=getchar();
printf("%c,%d\n",cl,cl);
c2=cl+32;
printf("%c,%d\n",c2,c2);

运行情况如下:
a
a,65
a,97
用 getchar函数得到从键盘上输入的大写字母‘ a?,
赋给字符变量 c1。将 c1分别用字符形式 (?a?)和整数形式 (65)输出。再经过运算得到小写字母‘ a?,赋给字符变量 c2,将 c2分别用字符形式 (?a?)和整数形式 (97)输出。
例 4.12求 ax2+bx+c=0方程的根。 a,b,c由键盘输入,
设 b2-4ac> 0。
众所周知,一元二次方程式的根为可以将上面的分式分为两项:
据此编写程序如下:
# include <m ath,h>
m ain();

float a,b,c,disc,x1,x2,p,q;
scanf("a=%f,b=%f,c=%f",&a,&b,
&c);
disc=b*b-4*a*c;
p=-b/(2*a);
q =sq rt(disc)/(2*a);
x1=p+q; x2=p-q;
printf("\n\nx1=%5.2f\nx2=%5.2f\n",x1,x2);

运行情况如下:
a=1,b=3,c=2
x1=-1,00
x2=-2,00
注意程序中用了预处理命令# include <math.h>。
4.8 习题
4.1 C语言中的语句有哪几类?C语句与其他语言中的语句有哪些异同?
4.2 怎样区分表达式和表达式语句?C语言为什么要设表达式语句?什么时候用表达式,什么时候用表达式语句?
4.3 C语言为什么要把输入输出的功能作为函数,
而不作为语言的基本部分?
4.4 若 a=3,b=4,c=5,x=1,2,y=2,4,z=-3,6,
u=51274,n=128765,c1=?a?,c2=?b?。想得到以下的输出格式和结果,请写出程序 (包括定义变量类型和设计输出 )。
要求输出的结果如下:
a= 3 b= 4 c= 5
x=1.200000,y=2.400000,z=-3.600000
x+y= 3.60 y+z=-1.20 z+x=-2.40
u= 51274 n= 128765
c1='a' or 97(ascii)
c2='b' or 98(ascii)
4.5 请写出下面程序的输出结果:
main()
{ int a=5,b=7;
float x=67,8564,y=-789,124;
char c='a';
long n=1234567;
unsigned u=65535;
printf("%d%d\n",a,b);
printf("%3d%3d\n",a,b);
printf("%f,%f\n",x,y);
printf("%-10f,%-10f\n",x,y);
printf("%8.2f,%8.2f,%.4f,%.4f,%3f,
%3f\n",x,y,x,y,x,y);
printf("%e,%10,2e\n",x,y);
printf("%c,%d,%o,%x\n",c,c,c,c);
printf("%ld,%lo,%x\n",n,n,n);
printf("%u,%o,%x,%d\n",u,u,u,
u);
printf("%s,%5.3s\n","coMputer",
"coMputer");

4.6 用下面的 scanf函数输入数据,使 a=10,b=20,
c1='a',c2='a',x=1.5,y=-3.75,z=67.8,请问在键盘上如何输入数据?
scanf("%5d%5d%c%c%f%f%*f,%f",&a,&b,
&c1,&c2,&x,&y,&z);3.7设圆半径 r=1,5,
圆柱高 h=3,求圆周长、圆面积、圆球表面积、圆球体积、圆柱体积。用 scanf输入数据,输出计算结果,输出时要求有文字说明,取小数点后 2位数字。请编程序。
4.7 输入一个华氏温度,要求输出摄氏温度。公式为 c=5/9(f-32)
输出要有文字说明,取 2位小数。