《C语言的语法基础.pptx》由会员分享,可在线阅读,更多相关《C语言的语法基础.pptx(170页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、2.1.1 标识符与基本数据类型标识符 基本型数据类型 返回目录第1页/共170页标识符 标识符(indentifier)是一个名字,在语言中标识符就是常量、变量、类型、语句、标号及函数的名称。程序设计语言中的标识符均有其命名规则。语言中标识符有三类,关键字、预定义标识符和用户定义标识符。()关键字已被系统所使用的标识符称为关键字,每个关键字在程序中都有其特定的作用,关键字不能作为用户标识符。以下是Turbo 2.0 的关键字共43个,所有关键字中只包含小字母和下划线。返回目录第2页/共170页由ANSI标准定义的共32个关键字,见表2.1 返回目录第3页/共170页Turbo 2.0 又增加
2、了11个扩展的关键字,见表2.2返回目录第4页/共170页()预定义标识符C语言系统提供的库函数名和编译预处理命令等构成了预定义标识符。在程序中若使用了库文件包含,就把相应的预定义标识符定义在程序中了,程序设计时就可以使用这些预定义标识符。有少数预定义标识符可以直接使用,而不用在程序中使用库文件包含。返回目录第5页/共170页例如:在程序中不加#include“stdio.h”库文件包含,也可以调用 printf、scanf 这两个函数。如果程序中没有相应的库文件包含,用户可以定义标识符与系统预定义标识符一样的名称,但应尽量避免这样做。因为语言系统已经规定了预定义标识符的特定含义,用户再定义与
3、之相同的名字,便强行改变了系统原来赋予该标识符的意义,导致使用上的混淆。返回目录第6页/共170页例如:若程序中没有#include“stdio.h”(相应的库文件包含),用户就可以定义putchar作为用户的函数名,但这与系统原有的预定义标识符putchar同名,调用该函数时,常常不清楚是调用系统的函数putchar还是调用户定义的函数putchar。因此应尽量避免使用预定义标识符作为用户标识符。返回目录第7页/共170页()用户标识符用户可以根据需要对程序中用到的变量、符号常量、用户函数、标号等进行命名,成为用户标识符。在Turbo 2.0 中,用户标识符必须满足以下规则:标识符必须由英文
4、字母、下划线、数字组成,不能包含其它字符(如 全角字母 和全角数字不能用于标识符);标识符必须由英文字母或下划线打头;标识符的长度不能超过32个字符;标识符大小写字母有区别(代表不同的标识符);标识符不能使用Turbo 2.0 的关键字。返回目录第8页/共170页用户在定义标识符时应注意以下事项:禁止使用Turbo 2.0关键字作为用户的标识符;尽量避免使用预定义标识符作为用户标识符;标识符中不能出现全角字符、空格,不要把下划线“_”写成减号“-”;标识符必须先定义后使用,使用未经定义的标识符将出现编译错误;使用的标识符最好做到见名知义,以增加源程序的易读性和易维护性。例如area 表示面积,
5、sum 表示求和等;在同一函数(的不同复合语句)中,最好不要定义相同的标识符作变量名。返回目录第9页/共170页表2.3 举例说明了标识符的使用:返回目录第10页/共170页 程序是由处理对象和处理方法这两个主要要素组成。处理方法指的是算法和程序设计方法,而处理对象指的是数据结构。通常说的“程序数据结构算法”就包含了这个意义。因此数据是程序的重要组成部分。数据有一个非常重要特征即数据的类型。数据类型不仅确定了变量的性质、取值范围、占内存空间大小,而且还确定了变量所能参加的各种运算方式。基本型数据类型返回目录第11页/共170页 例如一个整型(int)类型的数据,在IBM PC系列微机上取值范围
6、规定为-3276832767之间的整数,占内存空间字节,能参与算术运算、位运算等。C语言中,每个变量在使用之前必须定义其数据类型,每个常量也必须属于对应的数据类型。语言的数据类型如图2.1所示,本节将介绍基本数据类型。构造数据类型分别在第四章和第五章中介绍。返回目录第12页/共170页返回目录第13页/共170页2.1.2 常量与变量常量 2.变量返回目录第14页/共170页常量 在程序执行过程中,值不能被改变的量称为常量。如123,3.15,A,“Hello”,均是常量。在语言中有整型常量、实型常量、字符型常量、字符串常量和符号常量五种类型。()整型常量 整型常量就是整数。语言的整型常量有三
7、种表示形式:十进制整数。不由数字0开头的整数组成,可以由数字0至数字9组成,前面可加正号“+”或负号“-”。如:123、+4560、-987都是十进制常量。返回目录第15页/共170页八进制整数。由数字0开头的整数组成,只能由数字0至数字7组成,前面可加正号“+”或负号“-”。例如:07623、-04567、+0315都是八进制整常量。如果写成0891则是错误的,八进制数不能含有数字和数字。十六进制整数。由数字0和字母x(或X)开头的数组成,可以由数字0至数字9、字母a至字母f或字母A至字母F组成,前面可加正号“+”或负号“-”。如0 xa3f、-0X9A、0 x345、+0X6ab都是十六进
8、制整型常量。返回目录第16页/共170页使用整型常量应注意下面事项:一个整型常量的尾部加上字母l或L时,则为长整型(long 或long int)常量。例如:123l为十进制的长整型常量、0123L为八进制的长整型常量、-0 x123L为十六进制的长整型常量。长整型常量往往用于函数调用中,如果函数的形参为长整型,则实参也必须是长整型。返回目录第17页/共170页 一个整型常量也可以由它的值确定它的类型,如果其值在-3276832767范围内,则认为它是整型(int)常量;如果其值超出上述范围,而是在-21474836482147483647范围内,则认为它是长整型(long或long int)
9、常量。返回目录第18页/共170页()实型常量 实型常量就是实数。语言中实型常量用两种形式表示:小数形式:一个实数的表示包括数字和小数点。例如:1.23456、-0.465、+789.123、0.0、1.0等。指数记数法形式:这时实数包括整数部分、小数点、小数部分和指数部分,指数部分前加字母e或E。例如:1.2345e3、12.345E2、1.2345e03、1.2345e+3均表示1234.5这一实数。又如:0.123e+5、1e-4、35.69E11均为合法的实数表示。用指数形式表示实数时,指数部分必须是整数,字母e或E之前必须有数字。例如:123e5.6、e5、.e9、e等均为不合法的指
10、数形式。返回目录第19页/共170页上述两种表示方法所表示的实型常量都是双精度实型(double),双精度实型常量在内存中占8个字节,取值范围在1.710-3081.710+308之间。Turob C中,在双精度实型常量后加一字母l或 L则构成长双精度实型常量(long double),长双精度实型在内存中占10个字节,取值范围在3.410-49321.110+4932之间。返回目录第20页/共170页例如1.23e1234l、5.67e-3456L均为正确的长双精度实型常量。由实型常量的表示范围可知实型常量总是取正值。如果要使用负值,可在实型常量的前面加一个负号,构成常量表达式,其中的负号处
11、理成算术操作符。实型常量只有十进制实型常量一种,没有八进制实型常量,也没有十六进制实型常量。绝对值小于1的实型常量,其小数点前面的零可以省略,如:0.123可写为.123,-0.0123e-5可写为-.0123e-5。返回目录第21页/共170页()字符型常量语言的字符常量是ASCII码字符集里的一个字符,包括字母(大、小写有区别)、数字和标点符号以及特殊字符等,均为半角字符,一个字符常量在内存中占1个字节,因此字符常量不能是全角字符。语言字符常量有三种表示方法:返回目录第22页/共170页把单个字符用一对单引号括起来表示字符常量。例如 a、6、A、+、:。用该字符的ASCII码值表示的字符常
12、量。例如十进制数65表示大写字母A,十六进制数0 x41也表示A,八进制数0101还表示大写字母A。一些不能用符号表示的特殊字符(如控制符等),可以用ASCII码值来表示,如换行可用10表示,也可用十六进制数0 x0a 或八进制数012来表示换行。返回目录第23页/共170页反斜扛“”开头后跟规定的单个字符或数字,并用一对单引号括起来表示字符常量。例如用r表示回车、用n表示换行。换行也可用12或012反斜扛后跟八进制数表示,应注意这里反斜扛“”后的八进制数、十六进制数前面的0可以省略,省略后并不表示成十进制数。换行还可用x0a或0 x0a反斜扛后跟十六进制数表示。这种表示法中反斜扛“”后面的字
13、符变成了另外的意义,我们称之为转义字符。表2.4列出了常见的转义字符常量。返回目录第24页/共170页返回目录第25页/共170页例2.1 main()printf(“123456789012345n”);printf(“ab ctdeb101fgn”);printf(“ab crde12x41n”);运行结果:123456789012345ab c dAfg de c A上例没有单个输出字符常量,而使用printf函数输出双引号内的各个字符。返回目录第26页/共170页 第一个printf输出一串数字,作为坐标参照。最后的n作用是回车并换行。第二个printf从第1列开始先输出“ab c”,
14、后遇到t光标移到下一输出区的开始位置(第9列),从第9列开始输出“de”,又遇到退格符b,光标退格(左移一格)在字符e的位置上输出101(字母A)以及“fg”,在第10列上字母A把字母e覆盖了,最后回车换行。第三个printf从第1列开始先输出“ab c”,后遇到r回车,光标移本行的第1列输出“de”,并把“ab”覆盖了,又遇到回车换行12,光标移到下行的第1列输出字符41(字母A),最后回车换行。返回目录第27页/共170页()字符串常量若干个字符用双引号括起来就构成了字符串常量。如“Good morning!“、”123“、“A”、“abcde”都是字符串常量。语言中在存储字符串常量时,除
15、了存储双引号中的所有字符之外,在串的最后还要存放一个字符0,表示该字符串常量到此结束。字符0也称为字符串结束标志。因此字符串常量“abcde”占内存个字节,字串结束标志0多占了一个字节。字符串常量“abcde”在内存是按如下方式存储的:返回目录第28页/共170页利用系统提供的输出函数printf和 puts可以将字符串常量整体输出到屏幕,利用输入函数scanf和 gets可以将字符串整体输入到内存。另外字符常量A,和字符串常量“A”不同,前者为字符常量可直接赋值给字符变量,而后者为字符串常量可以存放到字符数组中,也可以赋值给字符指针变量,A占内存1个字节,而A 占内存2个字节,字符串结束标志
16、0多占了一个字节。返回目录第29页/共170页()符号常量语言中可以用一个标识符来代表一个常量,这个标识符就称为符号常量。可以用两种方式来定义语言中符号常量。利用宏定义#define 来定义符号常量。例如:#define PI 3.14159#define ESC 27#define ID 102343-3852396-y3v4x5a则PI、ESC与ID是符号常量,在程序中它们的值不能被改变。程序中用符号常量来代替一串不易记意的数字或一串字符串,不仅增加了程序的可读性,也减轻了程序设计人员的负但。另外,用一串较短的字串来代替一串长字符串,也提高了编写效率。语言中习惯用大写字母表示符号常量。返回
17、目录第30页/共170页 利用“const”来定义符号常量,这一方法在定义符号常量的同时也定义了该常量的数据类型。用const来定义符号常量的格式为:const 数据类型关键字 符号常量1=常量1,符号常量2=常量2,.;例如:constint MAXINT=32767;constlong int MAXLONG=2147483647;定义符号常量MAXINT为整型、MAXLONG为长整型。返回目录第31页/共170页变量 在程序执行过程中,可以改变值的量称为变量。变量有以下几个特征:变量名、变量值、变量的数据类型、变量的地址、变量的存储类别、变量的作用域以及变量的生存期等。变量名是指按照语言
18、标识符的规则,给变量取的名称,使用变量名就可以存取变量的值。返回目录第32页/共170页 一个变量在内存中占有一定的存储空间,这个存储空间内所存放的数据就是变量的值。变量的数据类型确定了该变量的性质、取值范围、占内存空间大小以及所能参加运算的方式。有关变量地址的概念我们将在下一节讨论。在第六章讲述变量的存储类别、变量的作用域以及变量的生存期等。返回目录第33页/共170页 在语言中变量必须先定义才能使用。变量一经定义数据类型,计算机系统就会给该变量分配相应的存储空间,以便存放数值。一条变量定义语句由数据类型,其后跟一个或多个变量名组成。变量定义的格式如下:数据类型关键字;变量名表是一个或多个标
19、识符,每个标识符之间用逗号“,”分开。返回目录第34页/共170页例如:int i,j,k;上述语句定义了三个变量,它们的名字分别为i、j、k,数据类型为整型,它们可以存取整型数据,变量的取值范围是-3276832767,占内存空间2个字节,可参于算术运算、位运算等。表2.5给出了Turbo 2.0 基本数据类型关键字,还给出了在IBM PC系列微机上相应数据类型所对应的变量占存储空间大小以及变量的取值范围。返回目录第35页/共170页返回目录第36页/共170页表2.5中long int 可简写为long,short int 可简写为short,unsigned int 可简写为 unsig
20、ned。表2.5列出的是IBM PC系列微机上基本数据类型所占内存字节数及数据的取值范围,不同类型的机型表中数据有所不同,使用时可查阅相关手册。本书的叙述、举例均按表2.5中的数据为标准。下面我们举例说明如何定义变量:返回目录第37页/共170页 int i,sum;定义i,sum为整型变量 long k,suml;定义k,suml为长整型变量 double x,y;定义x,y为双精度实型变量 float x1,x2;定义x1,x2为单精度实型变量 char ch;定义ch为字符型变量 unsigned u;定义u为无符号整型变量返回目录第38页/共170页 变量的初始化:定义变量时,在变量之
21、后加“=常量”,则对该变量进行了初始化。变量初始化过程是在定义变量类型时,把“=”号左边的常量赋值给变量。例如:int i=0,j=0;上述语句定义i,j为整型变量,并把常量0赋给i变量与变量j,这一初始化过程是在程序执行到本函数时给变量赋初值的。除了第六章讲述的静态存储变量和外部变量的初始化是在编译阶段完成的之外,动态变量的初始化过程都是在执行时完成。因此,语句int i=0,j=0;等价于以下两条语句 int i,j;i=j=0;/*运行时赋初值,把0值赋值给变量i和变量j*/注意,若写成 int i=j=0;是非法语句。返回目录第39页/共170页 一个动态变量未经初始化、也对其未赋值,
22、其初值是不确定的。例如在某函数中有以下程序段:int i;printf(%dn,i);执行后输出结果是个不确定的整数值。静态存储变量和外部变量若未经初始化、也对其未赋值,其初值是确定的,通常是0值,详见第六章。返回目录第40页/共170页2.1.3 内存的概念 计算机内存是由一片连续的存储单元组成,操作系统给每个单元一个编号,这个编号称为内存单元的地址(简称地址)。地址(编号)通常由一组连续的整数组成,编号小的称内存低地址,编号大的称内存高地址。每个单元占1个字节(byte)大小,这样内存中每一个字节就有一个地址(编号)。计算机在执行程序时先要做一系列的工作,例如要把程序的机器指令、常量等装入
23、内存,在内存中为程序的变量分配存储空间等等。然后才完成程序设计预定的任务。返回目录第41页/共170页常量、变量在内存的存储情况经常用如图2.2(a)和图2.2(b)的形式表示,设在某程序中有以下定义变量的语句:int i=25,j=0 x1af,k=-25;long int s=-25;系统将在内存中为变量i,j,k各分配2个字节的连续存储单元,变量s分配4个字节的连续存储单元,并把相应的常量存储到该变量的地址所指的空间中。返回目录第42页/共170页设变量i分配到地址为3000、3001的2个连续存储单元,则这两个单元将存放常量25;设变量j分配到地址为3002、3003的2个连续存储单元
24、,则这两个单元将存放常量0 x1af;设变量k分配到地址为3004、3005的2个连续存储单元,则这两个单元将存放常量-25;设变量s分配到地址为3006到3009的4个连续存储单元,则这四个单元将存放常量-25;如图2.2(a)所示,描述了变量i,j,k,s在内存中存储空间分配情况。返回目录第43页/共170页 1个字节占二进制8位(bit),有符号整数在内存中采用补码表示方法(详见附录),有符号数的最高位表示符号位,符号位为0表示正数,符号位为1表示负数。补码表示方法中正数用二进制原码表示,负数则用补码表示。上述语句中整型int 类型25的二进制表示为0000 0000 0001 1001
25、,其补码(按位取反,未位加)是:1111 1111 11100111。长整型long int 类型25的二进制补码是 1111 1111 1111 1111 1111 1111 1110 0111。如图2.2(b)所示,描述了变量i,j,k,s的值在内存中按位表示情况。返回目录第44页/共170页无符号整数表示的都是正数,其最高位不是符号位,而是数据本身的一部分。假设内存中有一个二进制数据1111 1111 11100111,我们把它视为有符号整数int 类型,则值为-25,若把它视为有无符号整数unsigned 类型,则值为十六进制数0 xffe7(即十进制数65511)。因此,内存中同一个
26、数据,若将其视为不同的数据类型,其表现形式也不相同。返回目录第45页/共170页返回目录第46页/共170页返回目录第47页/共170页将一个字符型常量赋值给字符变量,并不把字符本身存到内存单元中,而是将该字符常量的ASCII码存储到内存单元中。例如字母A的ASCII码是0 x41(十进制数65),若有语句char ch=A;则变量ch在内存中按位的表示如图2.3所示。返回目录第48页/共170页假设内存中有一个二进制数据01000001,我们把它视为字符类型则值为A,若把它视为int类型,则值为65。例如在输出该数据时用printf(“%c,%dn”,ch,ch);则输出A,65。格式输出函
27、数printf将在下一节介绍。返回目录第49页/共170页2.2 基本输入、输出函数2.2.1 格式输入和格式输出函数2.2.2 非格式化输入、输出函数 返回目录第50页/共170页程序中通常应包含输入数据、处理数据和输出结果三个基本要素(见例1.1与例1.2)。对于微型计算机来说,常见的输入设备有键盘、鼠标、扫描仪、数字化仪等,常见的输出设备有显示器、打印机、绘图仪等。程序设计中可以从磁盘文件输入数据,也可以将数据输出到磁盘文件,因此磁盘文件是即可输入也可输出的设备。返回目录第51页/共170页在学习程序设计入门阶段,先学习由键盘输入数据(通常指定键盘为标准输入设备),并把数据输出到屏幕(通
28、常指定屏幕为标准输出设备)。在第八章中我们再介绍读写磁盘文件中的数据。语言没有提供输入、输出操作的语句。语言程序中的输入和输出完全依靠调用C语言的标准输入、输出函数来完成。Turbo 2.0 库函数提供了格式化输入、输出函数和非格式化输入、输出函数。返回目录第52页/共170页2.2.1 格式输入和格式输出函数printf函数 调用printf函数时应注意:printf函数的输出格式说明 scanf函数调用scanf函数时应注意:scanf函数的输入格式说明返回目录第53页/共170页printf函数 语言库函数提供了针对标准设备的格式输入函数scanf和格式输出函数printf。下面详细介绍
29、这两个函数的用法。printf函数 printf函数是格式化输出函数,用于向标准输出设备(通常指定为屏幕)按规定格式输出数据。printf函数的调用格式为:printf(格式化字符串,输出表列);其中格式化字符串包括两部分内容:普通字符与转义字符将按原样输出到屏幕;另一部分是“输出格式说明”,以%开始,后跟一个或几个格式字符,用来指定输出数据的格式。返回目录第54页/共170页输出表列是若干个需要输出的数据项,称为函数的参数,可以是常量、变量或表达式。各参数之间用“,”分开。输出数据项与前面的“输出格式说明”必须由左至右一一对应,一个“输出格式说明”对应一个输出数据项。例如有如下程序段:上述程
30、序段运行后结果如下:i=1,j=ff返回目录第55页/共170页此处格式化字符串中的普通字符 i、=、,、j、=以及转义字符n(回车换行)均原样输出到屏幕,数据项的输出格式分析如图2.4:返回目录第56页/共170页 调用printf函数时应注意:()格式化字符串中,格式说明与输出项从左到右的数据类型必须一一匹配,否则将输出错误结果。例如执行语句printf(“%d,%dn”,123,123.456);第一项123可以正确输出,第二项将输出错误结果。这是因为第二个格式说明“%d”要求与之对应的输出项是整型数据,但此时输出项是实型数据与之不匹配,产生输出错误;返回目录第57页/共170页()在格
31、式化字串中,格式说明与输出项的个数必须相同。如果格式说明的个数少于输出项的个数,多余的输出项不予输出。如果格式说明的个数多于输出项的个数,则对于多余的格式将输出不确定值;()printf在调用结束后将返回一个函数值,其值等于输出数据项的个数。返回目录第58页/共170页每个格式说明都必须用“%”开头,以一个格式字符作为结束,在此之间根据需要可以插入“宽度说明”、左对齐符号“-”、长度修饰符“l”和“L”等。()格式字符格式字符用于规定输出不同的数据类型,格式字符和它们的作用如表 2.6所示。printf函数的输出格式说明 返回目录第59页/共170页返回目录第60页/共170页()长度修饰符
32、长度修饰符加在%和格式字符之间,对于长整型数一定要加l。例如%ld表示输出一个十进制长整型数据项。长度修饰符及其作用见表2.7 返回目录第61页/共170页从上表可知:双精度实型数据的输出不必用%lf,只要用%f即可。但长双精度实型数据的输出必须加长度修饰符L。例如%Lf、%Le等。()输出数据所占的宽度输出数据的宽度,可以使用系统默认宽度,也可以指定输出数据的宽度,主要有以下几种方式:返回目录第62页/共170页系统默认宽度%格式字符(例如%d、%c、%u、%f.),输出数据所占的宽度由系统决定(通常取数据本身的宽度,不加空格)。下面的m、n表示非负整数,m是输出数据的宽度,n是输出数据小数
33、部分的宽度。整型数据的输出宽度%md、%mu、%mo、%mx,按m宽度输出数据,不足m个位数,左补空格(数据右对齐)。输出宽度m前加一个负号“-”则右补空格(数据左对齐)。当数据的实际宽度超过m位时按实际长度输出。表2.8例举了各类不同整型数据的输出,输出格式化字串中的“*”以原样输出,仅作坐标参照。返回目录第63页/共170页返回目录第64页/共170页 实型数据的输出宽度%m.nf、%m.ne、%m.ng,数据输出的总宽占m列,其中小数部分占n列,若数据自身宽度小于m列,则左补空格。有关小数据部分输出格式的规定如下:当输出数据的小数位多于指定的小数宽度n时,截去右边多余的小数,并对截去的第
34、一位小数做四舍五入处理;当输出数据的小数位少于指定的小数宽度n时,在小数的最右边补0。当输出数据的宽度大于指定的总宽度m时,小数部分仍按上述规则处理,整数部分原样输出。在输出宽度m前加一个负号“-”,若数据自身宽度小于m列,则右补空格。返回目录第65页/共170页应该注意并非所有输出的数字均是有效数字,单精度(float)位有效,双精度(double)位有效,长双精度(long double)位有效。格式说明中规定的数据宽度m和小数位宽度n再大也不能改变数据的存储精度,所输出的多余位的数字是无意义的。假设已有如下定义变量语句,float f=12345.678;double d=12345.6
35、789056789;long double ld=12345.6789056789e600l;表2.9举例说明了使用printf函数输出上述变量f,d,ld各类实型数据的输出。返回目录第66页/共170页返回目录第67页/共170页字符串的输出宽度%ms 输出宽度占m列,若字符串宽度小于m列,左补空格,若字符串宽度大于m列则原样输出字串。%m.ns 输出宽度占m列,但只取字符串的左端n个字符,n小于m,左补空格。在输出宽度m前加一个负号“-”,若字符串宽度小于m列,则右补空格。表2.10举例说明字符串型数据的输出。返回目录第68页/共170页返回目录第69页/共170页 字符数据的输出宽度%m
36、c输出宽度占m列,左补m-1个空格。在输出宽度m前加一个负号“-”,则右补m-1个空格。表2.11举例说明字符型数据的输出。返回目录第70页/共170页()在输出的数字前加“+”号 使用%+格式字符(如%+d、%+f等),可在输出的数字前加“+”号。例如 printf(%+d,%+d,%+10.2f,123,-456,12345.678);运行结果:+123,-456,+12345.68()在输出数据前加前导0 在指定输出宽度的同时,在数据前面的多余空格处填以数字0。例如 printf(%010d,%010.2fn,-123,12345.678);运行结果:-000000123,0012345
37、.68返回目录第71页/共170页()对输出的八进制数加前导0,对输出的十六进制数加前导0 x要在输出的八进制数加前导0,在输出的十六进制数加前导0 x,可在%号和格式字符o和x之间插入一个#号。例如 printf(“%#o,%#xn”,65,65);运行结果:0101,0 x41返回目录第72页/共170页 scanf函数 scanf是格式化输入函数,可以从标准输入设备(通常指定为键盘)上,以各种不同的格式读入数据到变量。scanf函数的格式为:scanf(格式化字符串,地址表列);其中格式化字符串包括以下三类不同的字符:()输入格式说明,“输入格式说明”与printf函数中的“输出格式说明
38、”基本相同;()空白字符,指空格键、回车键(Enter键)和制表键(Tab键);()非空白字符,语言的字符常量或字符串常量。返回目录第73页/共170页 地址表列是若干个需要读入数据的地址项。各个地址项之间用“,”分开。地址项必须是语言中合法的地址表达式,通常是变量的地址。此处的地址项称为输入项。例如有如下程序段:上述程序段运行后从键盘输入:123 456.789回车运行结果:i=123,f=456.789返回目录第74页/共170页 此处“&”是“地址运算符”,&i表示变量i在内存中的地址。scanf函数先遇到输入格式说明%d先读入一个整型数123,然后遇到输入格式说明%f,略去输入中的一个
39、或多个连续空白字符后,读入一个实型数456.789,读入的数据存入相应的内存地址中,如图2.5所示:返回目录第75页/共170页如果输入的第一个数据前面有空白字符,则也要先略去这些空白字符,再开始读入第一个数据。例如上述程序段运行后从键盘输入:回车回车123 456.789回车屏幕上输出结果不变:i=123,f=456.789返回目录第76页/共170页调用scanf函数时应注意:格式化字符串中,格式说明的类型必须与地址表列中输入项的类型由左至右一一对应匹配。如果类型不匹配,将不能读入正确数据。例如:int i;float f;scanf(%d%d,&i,&f);此处变量i可以正确读入数据,而
40、变量f得不到正确数据。第二个格式说明%d要求与之对应的输入项是整型变量的地址,但&f为实型数据的地址与%d不匹配,因此出错;返回目录第77页/共170页 当输入的数据少于输入项时,程序等待输入,直到所有输入项都读入数据为止,若有非法字符读入,scanf函数也结束输入。如下程序段 int i,j,k;scanf(%d%d%d,&i,&j,&k);当程序运行到上述scanf语句时,从键盘输入:123 456 回车此时把123赋值给变量i,把456赋值给变量j,由于还有一个输入项没有读入数据,程序等待输入,此时若再从键盘输入:789 回车把789赋值给变量k,scanf函数结束输入。返回目录第78页
41、/共170页如果输入的数据多于输入项时,多余的数据存储在输入缓冲区,留作下一个输入项的输入数据。系统为标准输入设备(通常指定为键盘)在内存开辟了一块区域作为输入缓冲区。由键盘输入的数据先存储在输入缓冲区中,程序再从输入缓冲区读取数据,没取完的数据就暂存于输入缓冲区中,等待程序取走;返回目录第79页/共170页 格式化字符串中,格式说明的个数应该与输入项的个数相同。若格式说明的个数少于输入项的个数时,scanf函数结束输入,多余的数据项没接收新的数据。例如下例程序段 int i=10,j=20,k=30;scanf(“%d%d“,&i,&j,&k);执行时由键盘输入:1 2 3回车 结果变量i的
42、值为1,j的值为2,但&k没有与之对应的格式说明,输入的数据3将不会赋给变量k,变量k仍保持原来的值30。多余的输入数据3存储在输入缓冲区,留作下一个scanf函数输入项的输入数据。返回目录第80页/共170页若格式说明的个数多于输入项的个数时,scanf函数结束输入,每个多余的格式说明将滤掉输入缓冲区中的一个输入数据。例如有如下语句段 int i,j,k;scanf(%d%d%d,&i,&j);scanf(%d,&k);执行时由键盘输入:10 20 30 40回车结果把10赋给变量i,20赋给变量j,第一个scanf函数中多了一个格式说明“%d”将输入的30滤掉,然后把40赋给变量k。返回目
43、录第81页/共170页系统将提示错误信息:Null pointer assignment(指定了空指针),说明使用方法不正确。要滤掉输入缓冲区中的一个输入数据,正确的方法是在%与格式字符之间加一个“*”号。例如把上面程序段的第一个scanf改成:scanf(“%d%d%*d”,&i,&j);“%*d”表示从输入缓冲区中读走一个数据后不赋给任何变量。这时再运行上述程序段读入数据时,30被跳过去,把40赋值给变量k。这样就不会出现错误信息了。返回目录第82页/共170页 从键盘输入数据时,输入的各数据之间用空白字符(空格键、回车键Enter或制表键Tab)隔开。空白字符可以一个,也可以连续几个。从
44、键盘输入数据时,按空格键或制表键后,左边的数据并没有被程序接收,需要最后按一下回车键,scanf函数才能接受从键盘输入的数据。返回目录第83页/共170页如果在格式化字符串中插入有某个非空白字符,输入数据时应输入一个与该非空白字符相同的字符,形成一一对应。例如下面程序段:int i=1,j=2,k=3;scanf(“%d,%d,%d”,&i,&j,&k);要求键盘输入的每个数据之间紧跟一个逗号,下面是正确的输入123,456,789回车以下也是正确的输入。123,456,789回车但是下面的输入不正确,123 456 789回车以下的输入也不正确:123;456;789回车返回目录第84页/共
45、170页因为在格式化字符中有逗号(“,”),就要求输入一个“,”与之对应,如果“,”这一字符没有找到,本句scanf函数就结束输入,后两种输入方法只能把123赋值给变量i,变量j,k的值不变,j的值仍为2,k的值仍为3。再如,执行下述语句时:scanf(i=%d,j=%d,k=%d,&i,&j,&k)正确的输入数据格式是:i=123,j=456,k=789回车返回目录第85页/共170页如果在格式化字符串中插入有若干空白字符(空格键、回车键和制表键),输入数据时只要输入一个(或多个连续空白字符)。例如有如下程序段:int i,j;scanf(%d%d,&i,&j);输入时两个数据之间应输入一个
46、(或多个)空白字符,以下各行的输入均正确,123456回车 123回车456回车 123456回车 这三种输入都把123赋值给变量i,456赋值给变量j。返回目录第86页/共170页 scanf函数的地址表列中的输入项是地址,不是变量名,因此普通变量前应加“&”地址操作符。但是对于字符串数组或字符串指针变量(见第四章和第五章内容),其变量名本身就是地址,不需要在它们前面加“&”地址操作符。scanf函数在调用结束后将返回一个函数值,其值等于有得到值的输入项的个数。返回目录第87页/共170页scanf函数的输入格式说明 每个格式说明都必须用%开头,以一个格式字符作为结束,在此之间根据需要可以插
47、入“宽度说明”、长度修饰符“l”和“L”等。()格式字符 格式字符用于规定输入不同的数据类型,格式字符和它们的作用如表 2.12所示。返回目录第88页/共170页()长度修饰符 长度修饰符加在%和格式字符之间,长整型数一定要加l。例如%ld表示输入一个十进制长整型数据项;双精度实型数据的输入必须加长度修饰符l。例如%lf、%le。长双精度实型数据的输入必须加长度修饰符L。例如%Lf、%Le。长度修饰符及其作用见表2.13 返回目录第89页/共170页()输入数据的宽度 scanf函数输入数据的实际宽度是由输入数据的结束标志决定的,因为在读入某数据项时,遇到结束标志则完成该数据项读入。结束标志有
48、三种 空白字符:空格键、回车键或制表键(TAB);宽度m:格式字符前可用一个整数m指定输入数据所占宽度,此时输入数据的宽度不能大于m。在scanf函数中,不能指定实型数据小数位的宽度;非法字符:由于非法字符的存在,构成了不正确的常量。例如在输入整数时输入123r5,此处字母r为非法字符。返回目录第90页/共170页 表2.14 举例说明scanf函数的用法。以下的各例句中,i,j为整型变量(int),k为长整型变量(long),ch为字符型变量(char),f为单精度实型变量(float),d为双精度实型变量(double),ld为长双精度实型变量(long double)。返回目录第91页/
49、共170页()关于格式说明%c 在scanf函数中的格式说明%c用于输入单个字符,这时从键盘输入的空白字符将作为有效字符输入。例如:char c1,c2,c3;scanf(“%c%c%c”,&c1,&c2,&c3);如果键盘输入:ABC 字符A 赋值给变量c1,字符赋值给变量c2,字符B 赋值给变量c3。使用格式说明%c时空白字符不作为数据间的间隔,因此作为下一个字符赋值给变量c2。回车键和制表键遇%c也同样赋值给相应的字符变量。返回目录第92页/共170页()连续使用多个scanf函数例2.2在程序中连续使用多个scanf函数时,应注意消除前一行输入的回车符。#include stdio.h
50、 main()int i,j;float x=0.0,y=0.0;char c1,c2;scanf(%d%d,&i,&j);scanf(x=%f y=%f,&x,&y);scanf(%c%c,&c1,&c2);printf(i=%d,j=%dn,i,j);printf(x=%6.2f,y=%6.2fn,x,y);printf(c1=%c,c2=%cn,c1,c2);返回目录第93页/共170页程序运行时,要求从键盘把1赋给i,2赋给j,1.1赋给x,2.2赋给y,a 赋给c1,b 给c2。键盘输入:12回车 x=1.1y=1.2回车 运行结果:i=1,j=2 x=0.00,y=0.00 c1=