论文部分内容阅读
摘 要:格式输入函数scanf和格式输出函数printf是C语言程序中使用较频繁的两个函数,其格式非常相像,容易混淆,本文特此给以以下几点区分。
关键词:C语言 scanf函数 printf函数
scanf函数和printf函数是C语言中最常用且功能最强的输入输出函数,这两个函数格式比较相像,使用时容易混淆的地方很多,让人很费解。以下给以几个容易混淆点的区分(注:运行结果都是基于VC++ 6.0运行环境)。
一. 两个函数的定义[1]
scanf函数称为格式输入函数,即按照用户指定的格式从键盘上把数据输入到指定的变量中。
scanf函数调用的一般形式:scanf("格式控制字符串",地址表列);
其中,格式控制字符串用于指定输入格式,格式控制串可以由格式字符串和非格式字符串两种组成。地址表列中给出各变量的地址。
printf函数称为格式输出函数,其功能是按照用户指定的格式,把指定的数据显示到显示器屏幕上。
printf函数调用的一般形式:printf("格式控制字符串",输出表列);
其中,格式控制字符串的作用与scanf函数相同,它可以由格式字符串和非格式字符串两种组成。格式字符串是以%开头的字符串,非格式字符串在输出是原样输出,在显示中起提示作用。输出表列给出各个输出项。
二、scanf函数和printf函数的易混点
1、 scanf函数输入数据时不能规定精度,但可以规定宽度[2]。如:scanf("%5.2f",&a);是不合法的,不能企图用此语句输入一个小数点后有两位的实数。
另外,scanf函数可以指定输入数据所占的列数,系统自动按它截取所需的数据。例如:scanf("%3d%3d",&a,&b); 输入:123456<回车>系统自动将123赋值给变量a,456赋值给变量b。
假设将上例改为scanf("%3d%3d",&a,&b);若输入1234<回车>,则a=123,b=4。
假设将上例改为scanf("%3d%3d",&a,&b);若输入12<回车>,则相当于变量a接收到了12,而变量b还没有接收到值,系统还会继续等待,直到输入一个值给b才结束scanf语句。
而对于printf函数,要求则没有那么严格。输出%md,m为指定的输出字段宽度,如果数据的位数小于m,则左端补以空格;若大于m,则按实际位数输出;输出%m.n,指定輸出的数据共占m列,其中有n位小数,如果数值长度小于m,则左端补空格;如果数值长度大于m,则按实际位数输出。
例如有以下程序段:int x=12; double y=3.141593;printf("%d%8.6f",x,y);的输出结果是(A)
A)123.141593B)123.141593 C) 12,3.141593D) 123.1415930
解析:本题考查printf函数的用法。格式字符%d表示按十进制整型数据的实际长度输出,格式字符%8.6f指定输出地数据共占8列,其中小数位占6列,总宽度包括小数点占1列,如果数值长度小于8,则左端补空格,而本题y的值3.141593正好占8列,小数位占6列,小数点占1列,恰好输出y的值,因此选A。
通过以上几个例子,我们可以得出,格式输入函数scanf函数的要求更为严格些,而格式输出函数printf函数的要求更宽松些,这也正符合人性化的特点,电脑作为现代人类社会的一个辅佐工具,人为的输入数据时应该尽量简单,给人减轻一些不必要的脑力劳动的负担,而电脑输出时,则要尽量满足数据本身的特点。
2、设有如下定义,下面各输入语句中错误的是(B)
struct student
{ char name[10]; int age;char sex; float score;} stud[3];
A) scanf("%s",stud[1].name);B) scanf("%d",stud[1].age);
C) scanf("%C",&stud[1].sex);D) scanf("%f",&stud[1].score);
解析:本题首先定义了一个结构体名为student的数组stud,这个数组有三个元素分别为stud [0], stud [1]和stud [2],这三个元素都分别有4个成员(姓名,年龄,性别,成绩),本题意在通过scanf函数给数组元素的某个成员赋值,这就涉及到scanf函数的格式问题,scanf函数调用的一般形式为scanf("格式控制字符串",地址表列);其中的地址表列必须是地址,C语言中的地址大致就三种,一种是由&引导的,如选项D,由于score成员是单精度型,其地址就是在score变量前加个寻址符号即可,选项B、C与D同理,很明显,选项B的age成员放在地址表列处就要加寻址符号&符号,所以本题选B。另外一种特殊的就是数组名,C语言的数组名代表数组首元素的地址,所以要用scanf函数给数组赋值,则地址表列直接写数组名就可以,而不必在数组名前加寻址符号&符号,如选项A正是如此,所以在scanf函数的地址表列不用加寻址符号&符号。还有一种地址表示方式,就是指针,如果scanf的地址表列放的是指针变量,由于指针本身代表的就是地址,所以也不用寻址符号&符号。
又例如[3]
#include
main()
{ char *a[ ]={"abcd","ef","gh","ijk"};
int i;
for(i=0;i<4;i++)
printf("%c",*a[i]);
}
程序运行后的输出结果是(A)
A) aegi B) dfhk C)abcd D) abcdefghijk
解析:main函数中定义了一个指针数组a,它有4个元素,其初值分别是"abcd"、"ef"、"gh"、"ijk"4个字符串的首地址。然后利用for循环语句进行输出,其中格式符%c表示只输出一个字符,而a[i]是一个地址,指向字符串的第一个字符,因此printf("%c",*a[i])函数输出第i个字符串中的第一个字母,即aegi,本题选A.
如果将printf("%c",*a[i]);改为printf("%s", a[i]);则选D。因为printf函数的输出表列变为a[i],很明显是个指针,它存储的是所指向的字符串的首元素地址,以%s输出,则直到碰到字符串结束标识符'\0'才停止输出,也就是说会输出a[i]所指的字符串。
通过以上两个例子我们可以总结出,scanf函数的地址表列只能是地址。而printf函数的输出表列可以是地址(指针变量,数组名,带&的变量)也可以是数值或数值型变量。
三、 结语
以上就是scanf函数和printf函数特别容易混淆的一些地方,对于初学C语言者,不要死记硬背它们的格式,而应该多巩固知识点,或者结合VC++ 6.0 软件就会事倍功半。希望以上分析对于从事C语言编程的人员能提供必要地帮助。C语言本身是一门丰富的语言,其语言变化丰富多样,有时简单的一道题只需改一个符号,整个题的运行过程运行结果就截然不同。所以对于每个知识点的把握一定要透彻,这样才能更好地驾驭这种语言。
注释:
[1][2]谭浩强.C程序设计(第三版).北京:清华大学出版社,2005:74-86.
[3]全国计算机等级考试历届笔试真题详解,二级C语言程序设计,天津:南开大学出版社,2011:140.
作者简介:岳娜莉(1986-),女,陕西渭南人,天津师范大学教育科学学院教育技术学2009级硕士研究生,研究方向:远程教育及网络技术。
关键词:C语言 scanf函数 printf函数
scanf函数和printf函数是C语言中最常用且功能最强的输入输出函数,这两个函数格式比较相像,使用时容易混淆的地方很多,让人很费解。以下给以几个容易混淆点的区分(注:运行结果都是基于VC++ 6.0运行环境)。
一. 两个函数的定义[1]
scanf函数称为格式输入函数,即按照用户指定的格式从键盘上把数据输入到指定的变量中。
scanf函数调用的一般形式:scanf("格式控制字符串",地址表列);
其中,格式控制字符串用于指定输入格式,格式控制串可以由格式字符串和非格式字符串两种组成。地址表列中给出各变量的地址。
printf函数称为格式输出函数,其功能是按照用户指定的格式,把指定的数据显示到显示器屏幕上。
printf函数调用的一般形式:printf("格式控制字符串",输出表列);
其中,格式控制字符串的作用与scanf函数相同,它可以由格式字符串和非格式字符串两种组成。格式字符串是以%开头的字符串,非格式字符串在输出是原样输出,在显示中起提示作用。输出表列给出各个输出项。
二、scanf函数和printf函数的易混点
1、 scanf函数输入数据时不能规定精度,但可以规定宽度[2]。如:scanf("%5.2f",&a);是不合法的,不能企图用此语句输入一个小数点后有两位的实数。
另外,scanf函数可以指定输入数据所占的列数,系统自动按它截取所需的数据。例如:scanf("%3d%3d",&a,&b); 输入:123456<回车>系统自动将123赋值给变量a,456赋值给变量b。
假设将上例改为scanf("%3d%3d",&a,&b);若输入1234<回车>,则a=123,b=4。
假设将上例改为scanf("%3d%3d",&a,&b);若输入12<回车>,则相当于变量a接收到了12,而变量b还没有接收到值,系统还会继续等待,直到输入一个值给b才结束scanf语句。
而对于printf函数,要求则没有那么严格。输出%md,m为指定的输出字段宽度,如果数据的位数小于m,则左端补以空格;若大于m,则按实际位数输出;输出%m.n,指定輸出的数据共占m列,其中有n位小数,如果数值长度小于m,则左端补空格;如果数值长度大于m,则按实际位数输出。
例如有以下程序段:int x=12; double y=3.141593;printf("%d%8.6f",x,y);的输出结果是(A)
A)123.141593B)123.141593 C) 12,3.141593D) 123.1415930
解析:本题考查printf函数的用法。格式字符%d表示按十进制整型数据的实际长度输出,格式字符%8.6f指定输出地数据共占8列,其中小数位占6列,总宽度包括小数点占1列,如果数值长度小于8,则左端补空格,而本题y的值3.141593正好占8列,小数位占6列,小数点占1列,恰好输出y的值,因此选A。
通过以上几个例子,我们可以得出,格式输入函数scanf函数的要求更为严格些,而格式输出函数printf函数的要求更宽松些,这也正符合人性化的特点,电脑作为现代人类社会的一个辅佐工具,人为的输入数据时应该尽量简单,给人减轻一些不必要的脑力劳动的负担,而电脑输出时,则要尽量满足数据本身的特点。
2、设有如下定义,下面各输入语句中错误的是(B)
struct student
{ char name[10]; int age;char sex; float score;} stud[3];
A) scanf("%s",stud[1].name);B) scanf("%d",stud[1].age);
C) scanf("%C",&stud[1].sex);D) scanf("%f",&stud[1].score);
解析:本题首先定义了一个结构体名为student的数组stud,这个数组有三个元素分别为stud [0], stud [1]和stud [2],这三个元素都分别有4个成员(姓名,年龄,性别,成绩),本题意在通过scanf函数给数组元素的某个成员赋值,这就涉及到scanf函数的格式问题,scanf函数调用的一般形式为scanf("格式控制字符串",地址表列);其中的地址表列必须是地址,C语言中的地址大致就三种,一种是由&引导的,如选项D,由于score成员是单精度型,其地址就是在score变量前加个寻址符号即可,选项B、C与D同理,很明显,选项B的age成员放在地址表列处就要加寻址符号&符号,所以本题选B。另外一种特殊的就是数组名,C语言的数组名代表数组首元素的地址,所以要用scanf函数给数组赋值,则地址表列直接写数组名就可以,而不必在数组名前加寻址符号&符号,如选项A正是如此,所以在scanf函数的地址表列不用加寻址符号&符号。还有一种地址表示方式,就是指针,如果scanf的地址表列放的是指针变量,由于指针本身代表的就是地址,所以也不用寻址符号&符号。
又例如[3]
#include
main()
{ char *a[ ]={"abcd","ef","gh","ijk"};
int i;
for(i=0;i<4;i++)
printf("%c",*a[i]);
}
程序运行后的输出结果是(A)
A) aegi B) dfhk C)abcd D) abcdefghijk
解析:main函数中定义了一个指针数组a,它有4个元素,其初值分别是"abcd"、"ef"、"gh"、"ijk"4个字符串的首地址。然后利用for循环语句进行输出,其中格式符%c表示只输出一个字符,而a[i]是一个地址,指向字符串的第一个字符,因此printf("%c",*a[i])函数输出第i个字符串中的第一个字母,即aegi,本题选A.
如果将printf("%c",*a[i]);改为printf("%s", a[i]);则选D。因为printf函数的输出表列变为a[i],很明显是个指针,它存储的是所指向的字符串的首元素地址,以%s输出,则直到碰到字符串结束标识符'\0'才停止输出,也就是说会输出a[i]所指的字符串。
通过以上两个例子我们可以总结出,scanf函数的地址表列只能是地址。而printf函数的输出表列可以是地址(指针变量,数组名,带&的变量)也可以是数值或数值型变量。
三、 结语
以上就是scanf函数和printf函数特别容易混淆的一些地方,对于初学C语言者,不要死记硬背它们的格式,而应该多巩固知识点,或者结合VC++ 6.0 软件就会事倍功半。希望以上分析对于从事C语言编程的人员能提供必要地帮助。C语言本身是一门丰富的语言,其语言变化丰富多样,有时简单的一道题只需改一个符号,整个题的运行过程运行结果就截然不同。所以对于每个知识点的把握一定要透彻,这样才能更好地驾驭这种语言。
注释:
[1][2]谭浩强.C程序设计(第三版).北京:清华大学出版社,2005:74-86.
[3]全国计算机等级考试历届笔试真题详解,二级C语言程序设计,天津:南开大学出版社,2011:140.
作者简介:岳娜莉(1986-),女,陕西渭南人,天津师范大学教育科学学院教育技术学2009级硕士研究生,研究方向:远程教育及网络技术。