C语言之顺序结构
该章内容:这章我们学习三大结构之一:顺序结构,它是程序从上往下顺序执行,是程序运行最简单的方式。printf和scanf函数使用和特例是必考知识。本章是考试的重点章节。
学习方法:从简单的顺序结构题目入手,逐步把难度加大,对比记忆printf和scanf函数。
第一节 表达式与语句
知识点:语句和表达式之间的联系;分号的使用;复合语句
重要程度:★★★
1、表达式与语句
“ 表达式 “ + ” ;“ = ”语句 ”。例如:
赋值表达式 |
赋值语句 |
算术表达式 |
算术语句 |
自加表达式 |
自加语句 |
x=9 |
X=9; |
x+y |
x+y; |
i++ |
i++; |
从图中可以很清楚的看见,表达式和语句的区别就是一个有分号,一个没有分号。这个分号是考试的重点,尤其是在上机考试的改错题目,最喜欢不写分号,我们要加一个分号!
2、空语句与复合语句
;
1、这个分号也是一个语句,称为“空语句”。“空语句”表示程序执行时不产生任何动作。注意:随意使用空语句会导致逻辑上出现错误,需要慎用。
2、所谓复合语句,就是把好几个语句复合到一起,那么用什么符号把多个语句复合到一起来?我们要记住是用花括号“{”把多个语句括起来组成了一个复合语句。
复合语句具体形式:{语句1;语句2;…… 语句n;}
3、顺序结构
程序中的多个语句按照语句从上往下出现的先后次序顺序逐条执行,这种执行方式是最基本的执行方式,称为顺序结构,是三大基本结构之一。
记住一句话:看到顺序结构就想到从上往下。
第二节 数据输出
考 点:pirntf函数的使用;printf两个参数的使用方法;格式说明符号对应的意思;
重要程度:★★★★(每年必考)
printf函数和scanf函数都是库函数,printf和scanf都不是关键字,他们只是预定义标识符。
1、printf函数第一个参数讲解
例1:printf("x=%d,y=%d",1,2);
第一个部分是用双引号括起来!第二部分是两个数据“1,2”,数据之间是用逗号隔开的。
第一部分的双引号中就有两种信息:一种是原样输出,一种是格式说明。其中原样输出的说明信息是“x= ,y= ”,包括第一个%d之后的逗号也是原样输出。双引号中还有两个%d,这两个%d就是格式转换说明,用于指定第二部分数据“1,2”的输出格式为整型。这里第一个“%d”对应第一个数字1,第二个“%d”对应第二个数字2,因此我们可以在屏幕上看到:x=1,y=2。
例2:printf(“the result is %d”,123);
这个程序中运行结果是可以在屏幕上看到:the result is 123。那么原样输出的说明信息是“the result is”,第一个部分的%d是要把输出数据列表的123以整型的格式输出。
例3:printf("x=%d,y%d",1,2);
这个程序运行的结果是可以在屏幕上看到:x=1,y2。那么我们可以看到比例一中的第一部分,我们少了个等号“=”,所以我们在输出时候,原样输出的信息就没有等号“=”。
2、printf函数第二个参数讲解
printf函数第二个参数可以是常量数据,也可以是变量,也可以是表达式。
例4:printf("x=%d",1); 输出数据列表是常量 屏幕显示:x=1
printf("x=%d",x); 输出数据列表是变量 若x为9,屏幕显示:x=9
printf("x=%d",x+y); 输出数据列表是表达式 若x+y为12,屏幕显示:x=12
第二个要记住的:各个数据之间用逗号分隔开。
第三个要记住:输出数据的个数与输出控制中的格式转换说明的个数相等,并且在顺序上要一一对应且类型匹配。注意一点:如果类型不匹配,这时系统并不报错,但不能得到正确的结果。
例5:printf("%d,%f",9.87,2);
这里是不会报错的,但是得不到正确的结果,因为,第一个格式说明“%d”表示要把输出数据按整数形式输出,而它对应要输出数据却是实数9.87,对应出错了。第二个格式说明“%f”是要把输出数据按实数形式输出,而第二个要输出的数据却是整数2,显然不匹配。
在输出控制中,格式说明的个数(也就是第一部分%d的个数)应与第二部分输出项的输出数据个数相同。
情况一:格式说明的个数 < 输出项的个数。处理方式:多于的输出项不予输出;
情况一的例子:printf("%d,%d",2,3,4);的输出结果为2,3。数据4不会被输出。
情况二:格式说明的个数 > 输出项的个数,处理方式:对多于的格式说明将输出不定值。
情况二的例子:printf("%d,%d",2);的输出结果为2,772。第二个数据是不定值。
例6:有以下程序(常考题型)
main( )
{ int a=888,b=999;
printf("%d\n",a,b);
}
程序运行后的输出结果是
A)错误信息 B)999 C)888 D)888,999
分析:在printf语句中,格式控制的格式说明只有一个“%d”,但是而输出列表项有两项“888,999”,即a和b。由于只有一个%d,输出的结果只有一个,即printf函数的第二部分中第一个出现的变量a的值。则正确的答案是:C。
3、printf函数中的格式说明
前面的例子中多次出现了由“%”加上一个字符的组成的格式转换说明,它是作为printf的输出控制的。这个是一定要牢记的,是考试的重点!
表1 格式说明对应的输出数据格式
格式说明 |
输出数据格式 |
%d或%i |
输出有符号的十进制整型数 |
%f |
输出单精度或双精度数且小数点后有6位小数数位 |
%c |
输出一个字符 |
%o |
输出八进制无符号形式整型数(不带前导0) |
%x或%X |
输出十六进制无符号形式整型数(不带前导0x或0X) |
%#o |
输出八进制无符号形式整型数(带前导0) |
%#x或%#X |
输出十六进制无符号形式整型数(带前导0x或0X) |
%u |
输出无符号的十进制整数 |
%e或%E |
以[-]m.ddddde±xx或[-]m.ddddde±XX的形式输出单精度或双精度数。d的个数由精度决定。系统隐含的精度为6, d的个数隐含为5。 |
说明:
1) 对于长整型数据的输出,一定要在%和d之间加上英文小写字母l,即格式%ld。
2) 对于双精度数据的输出,一定要在%和f或e之间加上英文小写字母l, 即格式%lf或%le。
3) 用表1所列出的格式说明时,系统自动决定输出数据所占的宽度,并采用右对齐的方式。
常考题型:
例7: 若有以下程序段(注意:n所赋的是八进制数)
int x=32767,y=032767;
printf("%d,%o\n",x,y);
执行后输出结果是
A) 32767,032767 B) 32767,32767 C) 32767,77777 D) 32767,077777
分析:整型变量x和y分别存放的是十进制整数32767和八进制整数32767。在printf语句中,把x和y两个变量分别按%d(十进制有符号的形式)和%o(八进制无符号形式)形式输出。那么得到的结果应该是32767,32767,即答案B正确。
例8:同例7相似,只是在printf函数中的%o之间加上#,变为%#o。
int x=32767,y=032767;
printf("%d,%#o\n",x,y);
那么该例子得到的结果为:32767,032767, 可以看到%o与%#o之间的区别。就是一个不要输出八进制中前导的0,而另外一个是要输出前导的0。
例9:若有以下程序段
int i=0xabc,j=0xabc;
i-=j;
printf("%X\n",i);
printf("%#X\n",i);
执行后输出结果是
A) 0X0 B) 0x0 C) 0 D) 0XABC
0 0 0x0 0xABC
分析:第一行:整型变量i和j里面存放的都是十六进制整数abc。第二行:执行i-=j;语句,i值变为0。第三行:在printf语句中,把i存放的整数0以%X(十六进制无符号形式)形式输出,得到的结果是0,第四行:把i存放的整数0以%#X形式输出,得到的结果是0x0。所以正确答案是C。
例10:若变量a,b已定义为int类型并赋值22和66,要求用printf函数以a=22,b=66的形式输出,请写出完整的输出语句______。
分析:根据题目要求,变量a、b要求以int类型输出,从表1中可知:输出时应使用格式说明%d来对应整型,同时输出的形式为a=21,b=55,那么也就是有一部分的内容要原样输出。这些内容是“a= ,b=”,所以在输出控制的双引号内,我们写上代码“a=%d,b=%d”。最后,整个需要输出语句为:printf("a=%d,b=%d",a,b);
重要说明:(考得很少)
1) 在%和格式字符之间加入一个整数来控制输出数据所占的宽度,如%5d,
情况一:整数指定的宽度大于实际输出数据的宽度。处理方式:数据的输出采用右对齐的方式,左边自动补空格;
情况二:整数指定的宽度小于实际输出数据的宽度。处理方式:以输出数据的实际宽度输出。
表2举例说明了未指定宽度和指定宽度时的对比结果。
表2 未指定宽度和指定宽度时的输出数据对比结果(“ ”代表空格)
输出语句 |
输出结果 |
printf("%d",625); |
625 |
printf("%2d",625); |
625 |
printf("%5d",625); |
625 |
printf("%f",1.25); |
1.250000 |
printf("%6f",1.25); |
1.250000 |
printf("%12f",1.25); |
1.250000 |
说明:在输出时,小数点占一位,对于float和double类型一定要保证小数后是六位,不足的补0。
2) 在%和格式字符f之间加入“整数1.整数2”来控制输出数据的格式时,如%3.2f。
“整数1”指定整个输出数据占的总宽度。“整数2”指定输出实数的小数部分的个数。
情况一:当实际输出数据的小数个数 > “整数2”指定的个数时。处理方式:截去多余的数据,并对截去的第一位小数做四舍五入处理。
情况二:当实际输出数据的小数个数 <“整数2”指定的个数时。处理方式:在小数的右边添0 补足。
重要的一句话:碰到“整数1.整数2”形式,首先用“整数2”处理小数部分,处理完后,在用“整数1”处理整个数据,包括已经处理好的小数部分。
表3 “%整数1.整数2f”的输出格式(“ ”代表空格)
输出语句 |
输出结果 |
printf("%3.3f",3.1415); |
3.142 |
printf("%3.5f",3.1415); |
3.14150 |
printf("%9.5 f",3.1415); |
3.14150 |
printf("%3.0 f",3.1415); |
3 |
3)%o和%#o之间及%x和%#x之间的区别。有#号的时候,八进制要输出前导0,十六进制要输出前导0x,但是有一点:输出前一定要把十进制转换成需要输出的十六进制或者八进制。(注意:#号对其它格式字符通常不起作用)。
表4 输出的八进制数、十六进制数前分别添加0、0x
输出语句 |
输出结果 |
printf("%o",254); |
376 |
printf("%#o",254); |
0376 |
printf("%x",254); |
fe |
printf("%#x",254); |
0xfe |
其它使用说明:
1) 输出“%”字符的方法,应该在格式控制中用两个连续的“%”,即“%%”来表示,也就是要
在格式控制中出现两个连续的“%”。
例11:printf("%%d",255);不会输出整数255。因为“%%”的意图是要输出一个“%”,这个时候“d”会当作一个字符按原样输出。同时,由于这时因为没有格式说明,整数254无法输出到屏幕上。输出到屏幕上的结果为“%d”。
例12:printf("%%%d",255); “%%”意图输出一个“%”,后面的“%d”是格式说明,对应后面的255。那么这个时候输出的结果是为%255。
2) 注意格式说明会导致结果不同。
printf(“%d”,65); 把65以整型输出,得到结果是65。
printf(“%c”,65); 把65以字符形式输出,得到结果是大写字母A。
3) int的输出的格式说明:%d
float输出的格式说明:%f
char 输出的格式说明:%c
字符串输出的格式说明:%s
double 输出的格式说明:%lf
long int 输出的格式说明:%ld
第三节 数据输入
考 点:scanf函数的使用;scanf两个参数的使用方法;格式说明符号对应的意思;
重要程度:★★★★
1、scanf函数的具体介绍
scanf函数的功能:使变量获得数值。
1)“输入控制”的含义与printf函数的“输出控制”相同,其作用是指定输入时的数据转换格式。
2)“输入数据列表”的含义:是一个或者多个合法的地址表达式。
2、scanf函数中的格式说明
scanf函数与printf函数的格式说明有很大的相同之处:
表5 格式说明对应的输入数据格式
格式说明 |
输入数据格式 |
%d |
输入十进制整型数 |
%i |
输入整型数,输入时可带前导0的八进制整数和带前导0x的十六进制整数 |
%c |
输入一个字符 |
%o |
输入一个八进制整型数 |
%x |
输入一个十六进制整型数 |
%u |
输入一个无符号的十进制整型数 |
%f |
以带小数点的形式或指数形式输入单精度或双精度数 |
重要说明:
1) 从键盘中输入的数据是多个,不是一个的时候。输入的多个数值数据之间必须用分隔符(包
括空格符、制表符和回车符)隔开。
例如:
int x, y, z;
scanf("%d%d%d",&x,&y,&z);
现在要对x, y, z三个整型变量分别输入100 200 300
则数据的输入形式可如下几种:
方法一:100<空格符>200<空格符>300<回车>
方法二:100<空格符><空格符>200<空格符>300<回车>
方法三:100<制表符>200<制表符300<回车>
方法四:100<回车>
200<回车>
300<回车>
这四种方式都是正确的。主要是在各个数据之间用分隔符隔开,分隔符符号有:包括空格符、制表符和回车符三种。
错误的输入: 100,200,300<回车>
2)重要的一点:scanf函数中第一个参数中,格式说明的类型必须和scanf函数中第二个参数输入项的类型一一对应匹配。如果类型不匹配,系统是不会给出出错信息,运行的结果是得不到正确的输入数据。如:
int a;
scanf(“%f”,&a);由于我们规定int格式说明为%d,所以这里%f就错了!
3)当输入长整型数据(long)时,必须使用%ld格式;输入double数据时,必须使用%lf或%le,否则不能得到正确数据,例如:
long a; scanf(“%lf”,&a); |
long a; scanf(“%f”,&a) |
格式正确,变量a可以得到正确数据。 |
格式不对,变量a得不到 正确数据。 |
4)与printf函数相似,在scanf函数中的格式字符前可以用一个整数指定输入数据所占的宽度,但对实数不能指定小数的位数,例如:
int a; scanf(“%3d”,&a); |
float a; scanf(“%5f”,&a); |
把键盘连续敲入的三个数据作为一个整体数据赋值给变量a。 输入: 12345 <回车> 变量a的结果为123 |
这里的处理,变量a是得不 到正确的数据,实数不能指定小数的位数。 输入: 123456.78<回车> 得到错误的结果 |
5)注意一点:输入控制中,格式说明的个数与输入项的个数应该相同。
情况一:格式说明的个数 < 输入项的个数。处理方式:系统自动结束输入,多余的数据没有被读入,但作为下一个输入操作的输入数据;
情况二:格式说明的个数 > 输入项的个数。处理方式:系统会自动结束输入。例如:
int x, y, z; scanf("%d%d",&x,&y,&z); |
int x, y, z; scanf("%d %d %d",&x,&y,); |
键盘输入下面数据: 10<间隔符>20<间隔符>30<回车> 由于在输入控制中只有两个格式说明%d,则只能对x和y变量分别输入10和20,而30不能被读入,只能作为以后其它输入的输入数据。 |
键盘输入下面数据: 10<间隔符>20<间隔符>30<回车> 由于输入项多于格式说明的个数,变量x,y获得正确的数据之后,系统会自动结束输入。多出的那个%d不起作用。 |
6)考试的重点:跳过输入数据的方法。具体形式为:在格式字符与%之间加入一个“*”,这样会使输入过程跳过某个输入的数据。例如如下的程序:
int x, y, z; scanf("%d%*d%d%d",&x,&y,&z); |
int x, y, z; scanf("%d%d%*d%d",&x,&y,&z); |
键盘输入下面数据: 10<间隔符>20<间隔符>30<间隔符>40<回车> 则系统会把10赋给变量x,跳过数据20,把30赋给变量y,把40赋值给变量z。 最后可以得知:x=10,y=30,z=40;数据20被跳过 |
键盘输入下面数据: 10<间隔符>20<间隔符>30 <间隔符>40<回车>则系统 会把10赋给变量x,把20 赋给变量y,跳过数据30, 把40赋值给变量z。 最后可以得知:x=10,y=20,z=40; 数据30被跳过 |
7)考试的重点(必考):若在scanf函数的第一个参数的输入控制串中含有其他的字符,则在输入时要求一一对应的位置原样输入这些字符。例如:
int x, y, z; scanf("x=%d,y=%d,z=%d",&x,&y,&z); |
int x, y, z; scanf("%d,%d,%d",&x,&y,&z); |
要求按照如下的形式输入: x=20,y=30,z=40<回车> scanf函数的第一参数:"x=%d,y=% d,z=%d",之间有x=,y=,z=,所以输入的时候,这些符号在键盘输入时候不可以少。否则得到数据不正确。 |
要求按照如下的形式输入: 20,30,40<回车> scanf函数的第一参数:"%d,%d,%d",之间是有逗号的,所以输入的时候,逗号不可以缺少。否则得到数据不正确。 |
重要注意:
1)scanf的输入分隔符有三种,不包含逗号。在使用键盘输入数据时,不能以逗号作为分隔符。如果需要以逗号作分隔符,则应该在格式控制字符串中使用逗号,例如
scanf("%d, %d, %d",&x,&y,&z); |
scanf("%d%d, %d",&x,&y,&z); |
由于在以上三个%d之间有逗号隔开,所以正确的输入为: 10, 20, 30<回车> |
由于在以上后两个%d之间有逗号隔开,前两个%d之间没有逗号所以正确的输入为: 10<.分隔符>20, 30<回车> |
2)一般情况下,我们操作scanf函数的时候,scanf的格式控制字符串中不要包含其它非格式控制符,否则往往容易让人混淆,也很难得到正确的数据。也就是说,在scanf中一般只使用格式控制符。不要出现:scanf(" the data is %d",&a);这样的写法,最简单、最佳的操作写法如:scanf(" %d",&a)。
3)使用scanf时,如果数据输入未能完成,则程序一直等待键盘输入,此时用户应该完成数据输入。也就是说,程序从上往下顺序结构运行,当运行到scanf函数的时候,就会停止,等待你从键盘输入数据给指定的变量,这个和前面学的赋值语句有相同的功能。如果在未输入数据的情况下键入回车,程序是没有任何反映,好像死机了一样。这时,只要用户输入数据即可。
4)其实通过scanf函数给变量赋值和直接使用赋值语句给变量赋值,都能使变量的值发生改变,但二者具有本质区别。
|
使用scanf语句给变量输入数值 |
使用赋值符号“=”语句给变量赋值 |
实现语句 |
scanf(“%d’,&x); |
x=10; |
获值方式 |
使用键盘动态的给指定的某个变量赋值。 |
将某一个固定的值在程序源代码中用赋值语句写死, |
运行结果 |
每次编译运行后,变量可从键盘赋不同的值,得到不同的运行结果。 |
每次编译运行后,用户无法改变该变量的值,每次执行的结果均相同。 |