1、 程序由算法和数据构成。程序由算法和数据构成。数据是算法的处理对象。要学习程序设计,首先要了解处理对象数据的特点。本章中我们讨论C语言中基本数据及其类型和基本的运算方法。2.1 数据类型数据类型 通过对上一章的学习,我们知道通过对上一章的学习,我们知道:不同的数据在计算不同的数据在计算机中的表示方法是不同的(如:定点数、浮点数、字机中的表示方法是不同的(如:定点数、浮点数、字符数据等不同类型),这是由计算机的二进制存储特符数据等不同类型),这是由计算机的二进制存储特性所决定的。性所决定的。在程序中要指定数据的类型,以便编译系统能够按指在程序中要指定数据的类型,以便编译系统能够按指定类型确定其表
2、示方法、字节个数、以及运算方式。定类型确定其表示方法、字节个数、以及运算方式。整型整型单精度型单精度型基本类型基本类型 实型实型字符型字符型双精度型双精度型枚举型枚举型数据类型数据类型空类型空类型指针指针 数数 组组构造类型构造类型 结构体结构体 共用体共用体图 2-1 C语言的数据类型l表表2-1中,给出了中,给出了Turbo C的基本类型名和长度以及取值范围。的基本类型名和长度以及取值范围。l234页的附录表页的附录表-12中,给出了中,给出了VC+的基本类型名和长度以及的基本类型名和长度以及 取值范围。取值范围。l需要指出的是:需要指出的是:(1)在各种)在各种 C的版本中的版本中:ch
3、ar、signed char、un signed char型型数据的长度都是数据的长度都是1个个字节。字节。(2)在)在VC+中中int与与long型数据在长度、取值范围是一致型数据在长度、取值范围是一致的的:-21亿亿+21亿。亿。在在Turbo C中中int与与short型数据在长度、取值范围是型数据在长度、取值范围是一致的:一致的:-32768 +32767。(3)需要指出的是)需要指出的是:char型与型与signed char型或型或unsigned char型型二者之一相同。二者之一相同。int型与型与short型或型或long型型二者之一相同。二者之一相同。具体如何,视不同编译系
4、统而定。具体如何,视不同编译系统而定。(4)在)在C语言中,字符型数据存放的是字符的语言中,字符型数据存放的是字符的ASCII码值。码值。有符字符型数据用一个字节的最高位作为符号位,低七位表有符字符型数据用一个字节的最高位作为符号位,低七位表示字符的示字符的ASCII码值。无符字符型用一字节的全部八位表示码值。无符字符型用一字节的全部八位表示字符的字符的ASCII码值。利用这个存储特点,码值。利用这个存储特点,C语言允许字符型语言允许字符型数据以其数据以其ASCII码值(整型数)参加数值运算。码值(整型数)参加数值运算。(5)在)在VC+和和Turbo C中,中,float型型数据的存储格式为
5、:数据的存储格式为:阶码占阶码占8位,尾数占位,尾数占23位,位,1位符号位,共位符号位,共32位;位;double型型数据的存储格式为:数据的存储格式为:阶码占阶码占11位,尾数占位,尾数占52位,位,1位符号位,共位符号位,共64位。位。Turbo C采用采用IEEE标准的浮点数据存贮格式。标准的浮点数据存贮格式。详见(美国)电子和电气工程师协会网站详见(美国)电子和电气工程师协会网站 http:/standards.ieee.orgThe Institute of Electrical and Electronics Engineers 从表中可以看出:从表中可以看出:C语言中基本数据类
6、型很多,语言中基本数据类型很多,短的、长的、有符的、无符的,变化丰富。初学者短的、长的、有符的、无符的,变化丰富。初学者可能感到比较困难,其实从数据的存储形式上来看,可能感到比较困难,其实从数据的存储形式上来看,归纳起来实质上只有归纳起来实质上只有两大类型的数据两大类型的数据 整型整型数据数据和和实型实型数据,即数据,即定点整数定点整数和和浮点数浮点数。2.2 常量与变量常量与变量2.2.1 常量常量 所谓所谓“常量常量”是指在程序运行过程中,是指在程序运行过程中,其值不能被其值不能被改变的量。改变的量。C语言中常量有语言中常量有整型常量整型常量、实型常量实型常量、字符型常量字符型常量、字符串
7、常量字符串常量、符号常量符号常量和枚举常量和枚举常量。本节将介绍上述除本节将介绍上述除枚举常量枚举常量外的所有常量,枚举常量外的所有常量,枚举常量在第九章中介绍。在第九章中介绍。1.整型常量整型常量 整 型 常 量 又 简 称 整 数,它 有 三 种 形 式:整 型 常 量 又 简 称 整 数,它 有 三 种 形 式:十进制整数、八进制整数、十六进制整数。十进制整数、八进制整数、十六进制整数。十进制整数十进制整数 十进制整数由09十个数字、正号、负号组成,正负号只能出现在最左边,表示一个整数时,正号可以省略,多位数时,最左边的数字不能为0。例如:123 597 425 0 0是合法的整数。而0
8、932是非法的整数表示方法。八进制整数八进制整数 八进制整数必须以0(零)开头并由07八个数字、正号、负号组成,正负号只能出现在最左边。例如:0123 0404045300是合法的八进制整数,而0128是非法的。十六进制整数十六进制整数 十六进制整数十六进制整数必须以必须以0 x或或0X开头开头,由由09,a,b,c,d,e,f(或(或A,B,C,D,E,F)这十六个符号和正负号组成,正负这十六个符号和正负号组成,正负号只能出现在最左边。例如:号只能出现在最左边。例如:0 x123 0Xfa10 x9a120 x0是合法的十六进制数。是合法的十六进制数。0 x12g x897a25b是非法的十
9、六进制数是非法的十六进制数。整型常量的后缀整型常量的后缀U和和LU和和L分别是分别是unsigned 和和long的第一个字母,可以跟在整型常量的的第一个字母,可以跟在整型常量的后面,以指明该整数为长整型常数(后面,以指明该整数为长整型常数(long型)、无符整型常数型)、无符整型常数(unsigned型)以及无符长整型整数(型)以及无符长整型整数(unsigned long型)。使用时型)。使用时U和和L可以小写。例如:可以小写。例如:长整型数:长整型数:32768l 0761L 0 xd1dL无符整型数:无符整型数:32768u 0 x2a7U 0277U无符长整型数:无符长整型数:555
10、ul0 xabcLU0722ul*对于TC编辑器:当一个整型常数的值是在3276832767之间,则该整型常量为int型,当它的值超过3276832767而在21亿21亿之间时,则该整型常量为long 型。通过使用L和U后缀,可以使在3276832767之间的int型常量成为long型常量或使有符常量成为无符常量。2.实型常量实型常量 实型常量又称浮点型常量,它有两种实型常量又称浮点型常量,它有两种表示方法:十进制小数形式和指数形式。表示方法:十进制小数形式和指数形式。十进制小数形式十进制小数形式 十进制小数由十进制小数由09十个数字、小数点、十个数字、小数点、正号、负号组成,正负号只能出现在
11、最左正号、负号组成,正负号只能出现在最左边。例如:边。例如:123.5032.45 .0 0.是合法的实型常量。是合法的实型常量。指数形式指数形式指数的一般形式如下:指数的一般形式如下:整数部分整数部分.小数部分小数部分en其中其中 中内容为可选,但中内容为可选,但“整数部分整数部分”和和“小数部分小数部分”二者至少选其一,不可全无。二者至少选其一,不可全无。en为指数部分,为指数部分,e可可大写,大写,n是一个是一个13位位的十进制整数(第一位可为的十进制整数(第一位可为0),),2e2表示表示2102,。例如:。例如:123.5E30.45e4 1E0120e5是合法的指数形式。是合法的指
12、数形式。-E5-1E2.05.e50.8Ek是非法的指数形式是非法的指数形式。实型常量的后缀实型常量的后缀F和和L 因为实型常量缺省的类型为双精度实型,为因为实型常量缺省的类型为双精度实型,为了达到存储、精度、类型转换的需要,可用后缀了达到存储、精度、类型转换的需要,可用后缀F和和L。F和和L分别是分别是float 和和long double的第一个的第一个字母,可以跟在实型常量的后面,以指明该实数字母,可以跟在实型常量的后面,以指明该实数为单精度实数(为单精度实数(float型)或长双精度实数(型)或长双精度实数(long double型)。使用时型)。使用时F和和L可以小写。例如:可以小写
13、。例如:单精度实数:单精度实数:32.768f1F1.2e3F长双精度实数:长双精度实数:1.2e309l0.1L5L3.字符型常量字符型常量 字符型常量字符型常量是用是用一对单引号一对单引号括起来的一个字符,括起来的一个字符,如:如:a ,A ,$,等。空字符也是字符,它等。空字符也是字符,它包含包含0个字符,它的值是个字符,它的值是0,可以表示为,可以表示为 ,也可以,也可以表示为表示为 0 ,程序中总是用,程序中总是用 0 表示空字符。表示空字符。在在C语言中还有另外一种字符常量,称为语言中还有另外一种字符常量,称为转义字转义字符(符(Escape Sequences),它是以反斜线(它
14、是以反斜线()开头的)开头的字符串字符串,通常也把它们称为控制字符,因为它们中的,通常也把它们称为控制字符,因为它们中的大多数具有控制功能,如大多数具有控制功能,如 n 代表换行符,在代表换行符,在printf函数中使用它可以实现换行的功能。函数中使用它可以实现换行的功能。C语言中的转义语言中的转义字符见表字符见表2-2。Escape Sequencea combination of two characters that produces a special effect within a text string.The 1st character is always a backslash
15、().转义字符是两个字符构成字符串组合,用于实现一种特殊效果。转义字符的第一个字符总是反杠 。Escape char.Meaning 0 null 空字符空字符 a alarm 响铃响铃 b back退格,从当前位置向前移动一格退格,从当前位置向前移动一格 f feed换页,从当前位置换到下一页开头换页,从当前位置换到下一页开头 n new line换行,从当前位置换到下一行开头换行,从当前位置换到下一行开头 r return回车,从当前位置换到本行的开头回车,从当前位置换到本行的开头 t tab key水平制表,水平换到下一水平制表,水平换到下一tab位置位置 back slash反斜线字符
16、反斜线字符 single quote单引号字符单引号字符 double quote 双引号字符双引号字符 ddd 000377范围里范围里1到到3位位8进制数字对应的进制数字对应的ASCII字符字符 xhh 0 x000 xff范围里范围里1到到2位位16进制数字对应的进制数字对应的ASCII字符字符在在C语言中,字符型常量是一个整数,其值是语言中,字符型常量是一个整数,其值是它所对应的它所对应的ASCII码的值码的值(见第见第222页附录页附录),字符型数据可以与数值型数据通用,即可以进字符型数据可以与数值型数据通用,即可以进行算术运算行算术运算。如:如:a 的值是的值是97,A 的值是的值
17、是65,的值是的值是39。也可以用也可以用ddd或或xhh来表示一个字符。以下都是表示水平来表示一个字符。以下都是表示水平制表符制表符 t:t 011 11 x09 x9 而而 a 也可以写成以下形式:也可以写成以下形式:141 x61 例2.1main()printf(Hello,Cn);printf(1101451541541575410312);printf(12/4=3tis a stringn);getch();运行结果:运行结果:Hello,C Hello,C 12/4=3 is a string4.字符串常量字符串常量 字符串常量是由双引号括起来的一串字符。如字符串常量是由双引号
18、括起来的一串字符。如:1234、中国,北京中国,北京 等。等。值得注意的是:值得注意的是:字符是用单引号括起来的,而字符字符是用单引号括起来的,而字符串是用双引号括起来的。串是用双引号括起来的。a 是字符,而是字符,而a是字符串是字符串。字符串可以为空串即包含字符串可以为空串即包含0个字符的串,表示为个字符的串,表示为 。C语言规定:在每一个字符串后,系统自动加一个语言规定:在每一个字符串后,系统自动加一个 0,作为字符串的结束标志符,以便判字符串的长度。由于作为字符串的结束标志符,以便判字符串的长度。由于这个原因,字符串的长度比实际长度大这个原因,字符串的长度比实际长度大1。空串的长度。空串
19、的长度为为1,而不是,而不是0。在使用字符串时,应当注意以下情况:在使用字符串时,应当注意以下情况:(1)单引号作为字符串的组成字符时,可以直接使用。单引号作为字符串的组成字符时,可以直接使用。例如:例如:printf(It s my book n );执行后输出为:执行后输出为:It s my book (2)一个字符串不能分写在两行或多行上,如果非要写在两一个字符串不能分写在两行或多行上,如果非要写在两行上,则可在前一行的字符串尾部加一个反斜线行上,则可在前一行的字符串尾部加一个反斜线 或者把不同或者把不同行上的字符串分别用双引号括起来。行上的字符串分别用双引号括起来。例如:例如:prin
20、tf(C programming language is powerfuln);或者:或者:printf(C programming language is powerfuln);5.符号常量符号常量 符号常量是代表一个字符序列的标识符(又称宏符号常量是代表一个字符序列的标识符(又称宏名)。一旦定义了一个符号常量,则它就与该字符序列名)。一旦定义了一个符号常量,则它就与该字符序列是等价的。是等价的。在在C语言中,定义符号常量的方法有三种:语言中,定义符号常量的方法有三种:一是使用编译预处理的宏替换功能一是使用编译预处理的宏替换功能#define;二是使用类型限定符二是使用类型限定符 const
21、 说明并初始化。说明并初始化。三是使用枚举类型来定义。三是使用枚举类型来定义。u 宏替换功能#define定义符号常量,格式如下:#define 标识符标识符 字符序列字符序列 其中:字符序列可以由任意字符组成,还可以是已经定义过的符号常量。符号常量应先定义后使用,可以出现在程序中的任何位置,习惯上尽量放在程序的前面且符号常量(宏名)用大写字母书写,以示与其它标识符的区别。需要指出的是:当一个标识符被定义成符号常量,则在编译时,编译预处理首先将程序中所有该标识符用相应的字符序列来替换,然后再进行后续处理。例如:#define PI 3.14159#define SPACE 等。例2.2#def
22、ine STR1 This is a main()#define STR2 joke#define M STR1 STR2printf(M);getch();运行结果:运行结果:This is a joke用#undef 取消已定义了的符号常量。例如:#undef M取消定义后,该符号常量(宏名)还可再定义并使用。取消定义后,该符号常量(宏名)还可再定义并使用。在实际应用中,在实际应用中,#define常用来常用来(临时临时)替换程序中的一些变替换程序中的一些变量名或函数名,以避免对源程序的多处修改。量名或函数名,以避免对源程序的多处修改。l诸如50,3.1416等在C+中称为literal
23、constants,即字面常量字面常量lliteral constants在使用中存在两方面问题:在使用中存在两方面问题:读者常难以理解常量的(物理)含义;当改变常量的值时,必须逐一的变更l在定义变量时,如果加上关键字在定义变量时,如果加上关键字const,则变量的值在程序运则变量的值在程序运行期间不能改变,这种变量称为行期间不能改变,这种变量称为常变量常变量(也称为也称为定义符号常定义符号常量量)。定义常变量的一般格式为:)。定义常变量的一般格式为:const 类型说明符常变量名类型说明符常变量名 常量值常量值;例如:例如:const int PASS_MARK=50;lIt is stan
24、dard practice in C/C+to use upper case when naming constants.This helps distinguish them from variables.常变量名应使用大写字母,以便与变量名区别常变量名应使用大写字母,以便与变量名区别使用常变量的例子:使用常变量的例子:const int PASS_MARK=50;main()printf(%d,PASS_MARK+1);getch();2.2.2 变量变量 所谓所谓“变量变量”是指在程序运行过程中,其值是指在程序运行过程中,其值可以被可以被改变改变的量。的量。变量用变量用变量名变量名来表示
25、,当程序运行时,系来表示,当程序运行时,系统为每一个变量分配一个内存单元并在变量名和该内统为每一个变量分配一个内存单元并在变量名和该内存单元地址间建立一一对应的关系,引用该变量名时,存单元地址间建立一一对应的关系,引用该变量名时,实际上就是引用该实际上就是引用该变量名所对应地址单元的内容变量名所对应地址单元的内容。如图如图2-2所示:所示:数据数据是有不同类型的,它们的长度、表示方法也各是有不同类型的,它们的长度、表示方法也各不相同,因此变量也应有不同的类型,用以存放各种不相同,因此变量也应有不同的类型,用以存放各种类型的数据。类型的数据。常量的类型常量的类型是通过书写形式确定的,是是通过书写
26、形式确定的,是隐式说明隐式说明的。的。变量的类型变量的类型则需要预先定义,是则需要预先定义,是显式说明显式说明的。的。在程序执行时,系统为已经定义的不同类型的变在程序执行时,系统为已经定义的不同类型的变量分配单元,如为一个量分配单元,如为一个char型变量分配一个型变量分配一个1字节的存字节的存储单元,为一个储单元,为一个float型变量分配一个型变量分配一个4字节的存储单元字节的存储单元等,并确定了数据在其中的存储形式。等,并确定了数据在其中的存储形式。变量定义的格式如下:变量定义的格式如下:类型定义符类型定义符 变量名表;变量名表;例如:例如:int student_num;float s
27、tudent_score,aver;其中,类型定义符(见表其中,类型定义符(见表2-1)定义变量名表中所列)定义变量名表中所列变量的类型,变量名表由一个或多个变量名组成,其间变量的类型,变量名表由一个或多个变量名组成,其间用逗号分隔,变量名的命名应符合用逗号分隔,变量名的命名应符合C语言标识符的规定。语言标识符的规定。定义变量时,可以在定义的同时对变量进行初始化定义变量时,可以在定义的同时对变量进行初始化(赋初值),其格式如下:(赋初值),其格式如下:类型定义符类型定义符 变量名变量名=表达式,表达式,;例如:例如:long distance=700000,height;double area
28、=9.6e7;float s=3*distance;其中,变量名其中,变量名=表达式中的表达式中的“=”称为赋值号,其称为赋值号,其含义是将含义是将“=”右边表达式的值赋给其左边的变量。右边表达式的值赋给其左边的变量。在定义变量时,应注意以下几点:在定义变量时,应注意以下几点:(1)在使用变量时,应注意)在使用变量时,应注意“先定义,后使用先定义,后使用”的的原则。原则。C语言程序中,使用的任何变量必须在使用前已语言程序中,使用的任何变量必须在使用前已经定义过,否则编译会给出错误信息经定义过,否则编译会给出错误信息 undeclared identifier。(2)一般在)一般在一个函数中,变
29、量名不能重复定义一个函数中,变量名不能重复定义,如,如果重复定义,则编译会给出错误信息果重复定义,则编译会给出错误信息 redefinition。(3)除非有特定的需要,)除非有特定的需要,通常把定义变量的语句集通常把定义变量的语句集中放在函数的开始处中放在函数的开始处,在,在C语言程序中,将变量定义语语言程序中,将变量定义语句放在不同的位置,其含义有所不同,随意放置可能引句放在不同的位置,其含义有所不同,随意放置可能引起不必要的错误。起不必要的错误。建议:建议:初学者加强对不同类型数据之表示方法初学者加强对不同类型数据之表示方法以及存储方式的理解以及存储方式的理解。如:int a;语句定义了
30、一个什么类型的变量,变量名是什么?该变量所对应的内存单元有几个字节?是有符还是无符的?数据范围是多少?float a;或 double a;或 long a;呢?注意:注意:计算机内部是以二进制处理数据的,因此会产生误差:main()float x=3.1;printf(%.8f,x);getch();显示的是:显示的是:3.0999999指针的概念指针的概念n 指针是指针是C语言最具特色的语言成分。也是语言最具特色的语言成分。也是C语言最语言最具争论的语言成分。具争论的语言成分。n 简单地说,指针就是地址。简单地说,指针就是地址。地址是计算机内存管理中的重要概念。计算机内地址是计算机内存管理
31、中的重要概念。计算机内存中的变量,指令的存取均是通过地址来进行的。存中的变量,指令的存取均是通过地址来进行的。例如,在程序中对变量的访问是通过变量名进行的例如,在程序中对变量的访问是通过变量名进行的,而实际上系统是通过变量的地址来访问变量的。,而实际上系统是通过变量的地址来访问变量的。定义存放3的整型变量a可以用:int a=3;而定义存放变量而定义存放变量a所在内存的地址所在内存的地址2006,就要用指针变量了:就要用指针变量了:int*p;2006ap32006也就是说:也就是说:int*p 定义了一个可以存放任何整型变定义了一个可以存放任何整型变量地址的指针变量量地址的指针变量p。要想让
32、上边的要想让上边的a的地址的地址2006存入到存入到p里面,可以用赋值里面,可以用赋值的方式:的方式:p=&a;或者在定义或者在定义p时就赋值:时就赋值:int*p=&a;main()/显示显示a的内存地址的内存地址int a=3;int*p;p=&a;printf(%d,p);getch();l定义指针变量定义指针变量的一般形式是:类型标识符类型标识符 *指针变量名指针变量名例如:int*p;定义了一个指向整形变量的指针变量定义了一个指向整形变量的指针变量 p。通常,将指针和被指变量一起定义:int x,*p=&x;l指针变量是一种特殊的变量,它里面存储的数是另一个变指针变量是一种特殊的变量
33、,它里面存储的数是另一个变量的内存量的内存(首首)地址。地址。l指针变量必须先定义,并且指向了指定类型的变量指向了指定类型的变量(获得实获得实际地址值际地址值)后才能使用后才能使用。否则其值为随机数,获取其引用变量的值时出现运行错。l指针变量的类型是它指向的那个变量的类型。指针变量的类型是它指向的那个变量的类型。l在一个指针变量中只能存放同一类型变量的地址。在一个指针变量中只能存放同一类型变量的地址。否则造成数据提取的错误。在表达式中,可以使用在表达式中,可以使用&和和*两个运算符:两个运算符:l&取地址运算符取地址运算符 以变量名为操作数,以该变量的地址为值。如:p=&a;将a的地址送入p&
34、实现了指针变量的赋值。指针只有被赋值才有了意义。l*取指针指向对象运算符取指针指向对象运算符(指针运算符)以变量的地址为操作数,以该变量的值为值。如:*p 就是 指针变量p所指向的变量,也就是a。因此,p=&a将a的地址送入p,b=*p就将就将a的值赋给了的值赋给了b 即 printf(“%d“,a)与与printf(“%d“,*p)是一样的。是一样的。main()int x=3,*p=&x;printf(%dn,p);printf(%dn,&(*p);printf(%dn,x);printf(%dn,*(&x);getch();main()int a,b,*p1=&a,*p2=&b;a=10
35、0;b=10;*p1=*p1+2;/就是就是a+2 *p2=*p2+1;/就是就是b+1 printf(%d,%dn,*p1,*p2);p1=p2;/b的地址的地址p2赋给了赋给了a的指针的指针p1,/使得使得p1和和p2指向了同一个变量指向了同一个变量b的首地址。的首地址。printf(%d,%dn,*p1,*p2);getch();运行结果:运行结果:102,11 11,11 l在一个指针变量中只能存放同一类型变量的地址,在一个指针变量中只能存放同一类型变量的地址,否则造成数据提取的错误。否则造成数据提取的错误。l下边这个程序验证了指向类型不一致的错误结果下边这个程序验证了指向类型不一致的
36、错误结果:main()int x=3,*p;float*q;p=&x;q=&x;printf(%p%dn,p,*p);printf(%p%dn,q,*q);getch();运行结果:运行结果:0013FF7C 30013FF7C 0n由于由于p为整型指针,为整型指针,q为实型指针,在提取指向对象为实型指针,在提取指向对象x的值时的值时候就造成了不一致(应当都是候就造成了不一致(应当都是3)。)。2.3 运算符与表达式运算符与表达式 C语言的的特点之一就是运算符(Operator)多,涉及的运算范围广,使用时变化非常丰富。可以根据运算符的功能进行分类(见表2-3),也可以根据运算符所需操作对象操
37、作数(Operand)的个数分类。如:单目运算符(一个操作数)、双目运算符(两个操作数)、三目运算符(三个操作数)等。用运算符将若干个操作数连接起来构成的式子称为用运算符将若干个操作数连接起来构成的式子称为表达表达式式。单个的常量、变量、有返回值的函数调用也是表达式单个的常量、变量、有返回值的函数调用也是表达式(简单表达式简单表达式)。)。表达式运算的结果是一个值,称为表达式运算的结果是一个值,称为表达式的值表达式的值。表达式结果值的类型称为表达式结果值的类型称为表达式的类型表达式的类型。注意注意:(1)运算符对)运算符对操作数操作数有什么要求(有什么要求(类型、个数类型、个数等等)以及运算结
38、果的数据类型。)以及运算结果的数据类型。(2)运算符的)运算符的优先级别优先级别和运算符的和运算符的结合方向结合方向,它是决定表达式的运算规则的重要因素。运算符的它是决定表达式的运算规则的重要因素。运算符的优先级别与结合型见附录优先级别与结合型见附录。运算符运算符 名名 称称 表达式表达式 结果及类型结果及类型 +加法运算符或正值运算符(双目)加法运算符或正值运算符(双目)1+2.6 3.6 实型实型 减法运算符或负值运算符(双目)减法运算符或负值运算符(双目)31 2 整型整型 *乘法运算符(双目)乘法运算符(双目)4*3 12 整型整型 /除法运算符(双目)除法运算符(双目)4/3 1 整
39、型整型%模运算符或称求余运算符(双目)模运算符或称求余运算符(双目)8%5 3 整型整型 +正号运算符(单目)正号运算符(单目)+2.6 +2.6 实型实型 负号运算符(单目)负号运算符(单目)3 3 整型整型 表表2-42.3.1 算术运算符和算术表达式算术运算符和算术表达式算术运算符如表2-4所示:1.说明:(1)算术运算符是双目运算符,要求有两个运算对象,其中,+和 运算符还可作单目运算符。用算术运算符将运算对象(操作数)连接起来的式子称为算术表达式。(2)算术运算符优先级别的由高到低的顺序是:单目运算符+和、*、/、%、双目运算符+和。同级运算符的运算顺序是从左至右。(3)单目运算符+
40、和 的结合方向为从右至左,其它双目运算符的结合方向是从左至右。例如(3)(4)求余运算符%只能用于整型量之间,且以被除数的符号作为余数的符号。例如(4)(5)Turbo C提供了丰富的包括数学函数在内的库函数(见附录),以供编程使用。使用数学库函数时应在程序中加上编译预处理命令#include。在使用库函数时,应遵守函数对参数的要求,如:参数个数,参数类型以及参数的单位等。例如(5)另外,可以使用一对或多对()运算符,()的优先级别最高,其中的表达式优先运算。思考:5*2+8/2+2 与 5*2+8/(2+2)的值各为多少?go例如例如(3)表达式表达式5*2+8/2的值为的值为6,先算,先算
41、5(右结合,负(右结合,负号运算),再乘以号运算),再乘以2,然后处理,然后处理8除以除以2,最后完成加法。,最后完成加法。例如例如(4)表达式表达式5%2的值为的值为1,而表达式,而表达式5%2的值为的值为1。例如例如(5)#include 运行后结果为:运行后结果为:main()3.000000 float r=9.0;printf(“%fn”,sqrt(r);2.算术表达式的类型转换规则如下:算术表达式的类型转换规则如下:(1)算术表达式中,当操作数的类型相同时,其结算术表达式中,当操作数的类型相同时,其结果类型不变。果类型不变。例如例如(1)(2)在)在C语言中,字符型操作数可以以其语
42、言中,字符型操作数可以以其ASCII码码值参加算术运算。值参加算术运算。例如例如(2)(3)在)在C语言中,不同类型的操作数是可以进行混语言中,不同类型的操作数是可以进行混合运算的,其结果类型将按照规则发生变化。具体规合运算的,其结果类型将按照规则发生变化。具体规则参见则参见2.3.7节。节。go例如例如(1)5/2的结果不是的结果不是2.5而是而是2,就是因为这个原因。就是因为这个原因。例如例如(2)a +3的结果是整型数的结果是整型数100,因为,因为 a 的的ASCII码值为码值为97。2.3.2 赋值运算符和赋值表达式赋值运算符和赋值表达式赋值运算符赋值运算符以及以及复合赋值运算符复合
43、赋值运算符如表如表2-5所示:所示:算符算符 名名 称称 表达式表达式 等等 价价 于于 =赋值运算符(双目)赋值运算符(双目)a=6+2 +=加赋值运算符(双目)加赋值运算符(双目)a+=3 a=a+3 =减赋值运算符(双目)减赋值运算符(双目)a=4 a=a4 *=乘赋值运算符(双目)乘赋值运算符(双目)a*=9 a=a*9 /=除赋值运算符(双目)除赋值运算符(双目)a/=5 a=a/5%=运算符(双目)运算符(双目)a%=6 a=a%6 表表2-51.说明:说明:(1)赋值运算符)赋值运算符“=”的作用是将其右边表达式的值赋给其左边的作用是将其右边表达式的值赋给其左边的一个变量,用赋值
44、运算符将变量和表达式连接起来组成赋值表达的一个变量,用赋值运算符将变量和表达式连接起来组成赋值表达式。式。例如例如(1)(2)一个变量可以被多次赋值,一个变量可以被多次赋值,变量仅保存最后一次赋给的值变量仅保存最后一次赋给的值。赋值运算符赋值运算符“=”的右边可以是表达式,而左边只能是变量。的右边可以是表达式,而左边只能是变量。(3)赋值运算符不同于数学上的)赋值运算符不同于数学上的“等号等号”,a=b和和b=a再数学上再数学上是等价的,但在是等价的,但在C语言中,前者表示将变量语言中,前者表示将变量b的值赋给变量的值赋给变量a,而后而后者正好相反。者正好相反。(4)赋值表达式的值是赋给变量的
45、值。)赋值表达式的值是赋给变量的值。(5)赋值运算符是双目运算符,赋值运算符的优先级别相同,其)赋值运算符是双目运算符,赋值运算符的优先级别相同,其结合方向为从右至左结合方向为从右至左。算术运算符的优先级高于赋值运算符。算术运算符的优先级高于赋值运算符。例如例如(5)go例如例如(1)a=5 是一个赋值表达式,它表示将是一个赋值表达式,它表示将5赋给变量赋给变量a。例如例如(5)a=3+2 先算先算+,因为,因为+的优先级高。然后将的优先级高。然后将5赋给赋给a。运算运算完成后,变量完成后,变量a的值为的值为5,表达式的值为,表达式的值为5。a=b=7 先算先算b=7,因为因为=的结合方向为右
46、结合。赋值表达的结合方向为右结合。赋值表达式式b=7的值为的值为7,再将,再将7赋给赋给a。运算完成后,变量运算完成后,变量a和和b的的值为值为7,整个表达式的值为,整个表达式的值为7。a=(b=5)/(c=2)先算先算b=5,再算再算c=2,然后进行除法运算结然后进行除法运算结果为果为2,最终将,最终将2赋给赋给a。运算完成后,运算完成后,b的值为的值为5,c的值为的值为2,a的值为的值为2,整个表达式的值为,整个表达式的值为2。思考:思考:若变量若变量a已经有值且为已经有值且为9,那么表达式,那么表达式b=(a=4)/(b=a)的值是的值是1还是还是0?回答是?回答是1,为什么?,为什么?
47、2.赋值表达式的类型转换规则如下:赋值表达式的类型转换规则如下:(1)将)将整型数据赋给实型变量整型数据赋给实型变量时,数据以浮点时,数据以浮点数形式存储到实型变量中去,但值的大小不变。数形式存储到实型变量中去,但值的大小不变。例如:若已经定义例如:若已经定义float a,如果如果a=19,则将则将19转换转换成成19.00000(单精度实型有单精度实型有7位有效数字)位有效数字),然后然后赋给变量赋给变量a。若已经定义若已经定义double b,如果如果b=19,则赋给则赋给b的值是的值是19.00000000000000(双精度实型双精度实型有有16位有效数字位有效数字)。)。(2)将)
48、将实型数据赋给整型变量实型数据赋给整型变量时,舍去小数部时,舍去小数部分后,再赋给整型变量。这里要注意变量的类型分后,再赋给整型变量。这里要注意变量的类型(short、int、long)以及相应的数值范围,避免以及相应的数值范围,避免赋值后数据的溢出。例如:若已经定义赋值后数据的溢出。例如:若已经定义 float f=65538.0和和short i,如果如果i=f,那么就会那么就会出现数据溢出的错误,表现为显示错误的数字。出现数据溢出的错误,表现为显示错误的数字。main()float f=65538.0;short i;i=f;printf(%d%fn,i,f);getch();2 655
49、38.000000(3)将)将float型数据赋给型数据赋给double型变量型变量时,数值不变,有时,数值不变,有效位数扩展至效位数扩展至16位(小数点后补位(小数点后补0)。)。main()float f=65538.0;double i;i=f;printf(i=%lf f=%fn,i,f);getch();反之,将反之,将double型数据赋给型数据赋给float型变量型变量时,则截取时,则截取double型数据的前型数据的前7位有效数字,再赋给位有效数字,再赋给float型变量。这里,同型变量。这里,同样要注意数据溢出问题。样要注意数据溢出问题。main()double f=2200
50、0000000.0;float i;i=f;printf(i=%f y=%lfn,i,f);getch();(4)将)将整型数据赋给整型变量整型数据赋给整型变量时,要格外关注时,要格外关注两者间两者间长度长度(char、short、int、long)和和符号类符号类型型(singned、unsigned)上的差异,正是由于这上的差异,正是由于这些差异使得赋值完成后,变量里的值有所变化。些差异使得赋值完成后,变量里的值有所变化。具体如下:具体如下:将将“长的长的”(字节数多的)整型数据赋给(字节数多的)整型数据赋给“短短的的”(字节数少的)整型变量时,采取截断的方(字节数少的)整型变量时,采取截