1、第2章 数据类型和表达式 2.1 数据类型 2.2 常 量 2.3 变 量 2.4 运算符与表达式 数据类型是指定义了一组数据以及定义在这一组数据的操作,它是程序中最基本的元素。C+数据类型十分丰富,大体上可分为基本类型、空类型、构造类型、指针类型、类类型五种。如图2-1所示。数据类型基本类型空类型(无值类型)void构造类型类类型class指针类型整型int实型(浮点型)字符型逻辑型bool结构类型struct数组类型枚举型类型enum联合型类型union单精度型float双精度型double单字符型char宽字符型w-char图2-1 C+数据类型2.1 数据类型2.1.1 基本类型基本类
2、型基本数据类型有4种:整型(int)、浮点型(float)、字符型(char)、逻辑型(bool)。整型数在计算机内部一般采用定点表示法,用于存储整型量。(如123,-7等),存储整数的位数依机器的不同而异。浮点数和整数不同的地方是浮点数采用的是浮点表示法,也就是说,浮点数的小数点的位置不同,给出的精度也不相同。字符类型表示单个字符,一个字符用一个字节存储。逻辑类型,也称布尔类型,表示表达式真和假。2.1.2 空类型空类型void空类型void用于显示说明一个函数不返回任何值。还可以说明指向void类型的指针,说明以后,这个指针就可指向各种不同类型的数据对象。2.1.3 构造类型构造类型构造类
3、型又称为组合类型,它是由基本类型按照某种规则组合而成的。数组:是由具有相同数据类型的元素组成的集合。结构体:是由不同的数据类型构成的一种混合的数据结构,构成结构体的成员的数据类型一般不同,并且在内存中分别占据不同的存储单元。共用体:是类似于结构体的一种构造类型,与结构体不同的是构成共同体的数据成员共用同一段内存单元。枚举:是将变量的值一一列举出来,变量的值只限于列举出来的值的范围内。2.1.4 指针类型指针类型指针类型变量用于存储另一变量的地址,而不能用来存放基本类型的数据。它在内存中占据一个存储单元。2.1.5 类类型类类型类是体现面向对象程序设计的最基本特征,也是体现C+与C最大的不同之处
4、。类是一个数据类型,它定义的是一种对象类型,由数据和方法组成,描述了属于该类型的所有对象的性质。2.2 常 量常量是指在程序运行过程中其值不能改变的量。C+支持5种类型的常量:浮点型、整型、字符型、布尔型和枚举型。常量在程序中一般以自身的存在形式体现其值。常量具有类型属性,类型决定了各种常量在内存中占据存储空间的大小。2.2.1 整型常量整型常量整型数据表示通常意义上的整数,整型常量可以用十进制、八进制或十六进制表示。1.十进制常量十进制常量一般占一个机器字长,是一个带正负号的常数(默认情况下为正数),如+3,-7等。2.八进制常量八进制常量由数字0开头,其后由若干07的数字组成,如0378,
5、0123等。3.十六进制常量十六进制常量以0 x或0X开头,其后由若干09的数字及AF(或小写af)的字母组成,如0 x173,0 x3af。整型常量可以后跟字母l或L表示long型(长整数),也可以跟u或U表示unsigned整数(无符号整数),如以下数是合法的:375u/无符号整数12345UL/无符号长整数54321L/长整数 13579ul/无符号长整数2.2.2 浮点数常量浮点数常量浮点数也称为实型数。只能以十进制形式表示。共有两种表示形式:小数表示法和指数表示法。1.小数表示法小数表示法使用这种表示形式时,实型常量分为整数部分和小数部分。其中的一部分可在实际使用时省略,如10.2,
6、.2,2.等。但整数和小数部分不能同时省略。2.指数表示法指数表示法也称科学记数法,指数部分以E或e开始,而且必须是整数。如果浮点数采用指数表示法,则E或e的两边都至少要有一位数。如以下数是合法的:1.2e20,-3.4e-2。2.2.3 字符常量与字符串常量字符常量与字符串常量1.字符常量字符常量C+中的字符常量通常是用单引号括起的一个字符。在内存中,字符数据以ASCII码存储,如字符a的ASCII码为97。字符常量包括两类,一类是可显字符,如字母、数字和一些符号、+等,另一类是不可显字符常量,如ASCII码为13的字符表示回车。2.转义字符转义字符转义字符是特殊的字符常量,表示时一般以转义
7、字符开始,后跟不同的字符表示不同的特殊字符,表2-1列出了常用的特殊字符。名称符号空字符(null)0换行(newline)n换页(formfeed)f回车(carriage return)r退格(backspace)b响铃(bell)a水平制表(horizontal tab)t垂直制表(vertical tab)v反斜线(backslash)问号(question mark)?单引号(single quote)双引号(double quote)”表2-1 常用的特殊字符 3.字符串常量字符串常量字符串常量是由一对双引号括起来的零个或多个字符序列。字符串可以写在多行上,不过在这种情况下必须用反
8、斜线表示下一行字符是这一行字符的延续。字符串常量实际上是一个字符数组,组成数组的字符除显示给出的外,还包括字符结尾处标识字符串结束的符号0,所以字符串“abc”实际上包含4个字符:a、b、c和0。需要注意的是a和“a”的区别,a是一个字符常量,在内存中占一个字节的存储单元,而“a”是一个字符串常量,在内存中占两个字节,除了存储a以外,还要存储字符串结尾符0。2.2.4 布尔常量布尔常量布尔常量仅有两个:false(假)和true(真)。2.2.5 枚举常量枚举常量枚举常量可以通过建立枚举类型来定义。枚举类型是一种用户自定义数据类型。在声明枚举类型时,需要把常量的值一一列举出来,形式如下:enu
9、m 枚举类型名 常量值1,常量值2,常量值n;例如声明一个名为color的枚举类型:enum colorRed,Green,Blue,White,Black;枚举常量是一种符号常量。Red,Green等是符号常量,它们表示各个枚举值,在内存中表示以整型数。如果没有专门指定,第一个符号常量的枚举值就是0,其他枚举值依次为1,2,3。所以,C+自动给Red赋0,Green赋1,等等。2.3 变 量变量是指程序在运行时其值可改变的量。每个变量由一个变量名惟一标识,同时,每个变量又具有一个特定的数据类型。不同类型的变量在内存中占有存储单元的个数不同。2.3.1 变量名命名变量名命名变量名的命名要遵守以
10、下规则:不能是C+保留字。C+的保留字如表2-2所列。第一个字符必须是字母或下划线,中间不能有空格。变量名除了使用26个英文大小写字母和数字外,只能使用下划线。一般不要超过31个字符。变量名不要与C+中的库函数名、类名和对象名相同。例如,下列变量名是合法的变量名:a123 c3b file_1 asm auto break case catch char class const continuedefault delete dodoubleelseenumexternfloatforfriendgotoifinlineintlongnewoperatoroverloadprivateprote
11、ctedpublicregisterreturnshortsignedsizeofstaticstructswitchthistemplatethrowtrytypedefunionunsignedvirtualvoidvolatilewhile表2-2 C+的标准保留字 2.3.2 变量定义和说明变量定义和说明C+中,变量使用之前一定要定义或说明,变量定义的格式一般为:修饰符 类型 变量名;/注释其中,类型指出变量所存放的数据的类型;变量名是任意合法的变量名;注释指明该变量的含义和用途;修饰符进一步描述了变量的使用方式。修饰符和注释是任选的,可以没有。多个同一类型的变量可以在一行中定义,中间
12、用逗号隔开,也可以分别定义。例如:int a,b,c;/定义3个整型变量a,b,c和int a;/定义整型变量aint b;/定义整型变量bint c;/定义整型变量c二者等价。2.3.3 变量初始化变量初始化变量初始化一般采用两种方式。第一种方式是在定义变量时可以给变量赋一个初值,例如:int a=3;float b=3.4;const int c=5;第二种方式是先定义变量,然后通过赋值语句使变量初始化,例如:int a;a=3;2.4 运算符与表达式在程序中,表达式是计算求值的基本单位,它是由运算符和运算数组成的式子。运算符是表示进行某种运算的符号。运算数包含常量、变量和函数等。C+语言
13、的运算符按其在表达式中与运算对象的关系(连接运算对象的个数)可分为:单目运算(一元运算符,只需一个操作数)双目运算(二元运算符,需两个操作数)三目运算(三元运算符,需三个操作数)按其在表达式中所起的作用又可分为:算术运算符+-*/%关系运算符 =!=逻辑运算符!&|位运算符|&自增自减运算符+-赋值运算符=及其扩展(+=-=*=/=%=等)条件运算符?:指针运算符*和&逗号运算符,分量运算符*-函数调用运算符()下标运算符 求字节运算符 sizeof 强制类型转换运算符:(type)2.4.1 算术运算符算术运算符算术运算符有双目运算和单目运算两种。包括:+(加法运算符,或正值运算符,如1+2
14、,+3)-(减法运算符,或负值运算符,如1-2,-3)*(乘法运算符,如1*2)/(除法运算符,如1/2)%(模运算符或称求余运算符,如7%3=1)2.4.2 赋值运算符赋值运算符(1)赋值运算符“=”的一般格式为:变量=表达式;表示将其右侧的表达式求出结果,赋给其左侧的变量。例如:int i;i=3*(4+5);/i的值变为27(2)赋值表达式本身的运算结果是右侧表达式的值,而结果类型是左侧变量的数据类型。例如:int i=1.2*3;/结果为3,而不是3.6(3)赋值运算符的结合性是从右至左的,因此,C+程序中可以出现连续赋值的情况。例如,下面的赋值是合法的:int i,j,k;i=j=k
15、=10;/i,j,k都赋值为10(4)复合运算符:+=(加赋值),-=(减赋值),*=(乘赋值),/=(除赋值),%=(取模赋值),=(右移赋值),&=(与赋值),=(异或赋值),|=(或赋值)它们的含义如下:a+=b等价于 a=a+ba-=b 等价于 a=a-ba*=b 等价于 a=a*ba/=b 等价于 a=a/ba%=b 等价于 a=a%ba=b 等价于 a=a=b 等价于 a=ab a&=b 等价于 a=a&ba=b 等价于 a=aba|=b 等价于 a=a|b 例如:int a=12;a+=a;表示a=(a+a)=(12+12)=24;又例如:int a=12;a+=a-=a*=a;
16、表示a=a*a /a=12*12=144a=a-a /a=144-144=0a=a+a /a=0+0=02.4.3 关系运算符关系运算符(1)关系运算符用于两个值进行比较,运算结果为true(真)或false(假),分别用值非0(true)或0(false)表示。C+中的关系运算符如下:(小于),(大于),=(大于等于),=(等于),!=(不等于),(2)关系运算符都是双目运算符,其结合性是从左到右,、=运算符的优先级相同,=和!=运算符的优先级相同,前者运算的优先级高于后者。(3)关系运算符的优先级低于算术运算符。例如:a+bc等价于(a+b)ca!=bc 等价于 a!=(bc)2.4.4
17、逻辑运算符逻辑运算符&(逻辑与),|(逻辑或),!(逻辑非)逻辑表达式的结果为真则为1,结果为假则为0。逻辑非(!)是单目运算符,逻辑与(&)与逻辑或(|)为双目运算符。逻辑非的优先级最高,逻辑与次之,逻辑或最低。逻辑运算真值表如表2-3所示。表2-3 逻辑运算真值(真为非0,假为0)aba&ba|b!a!b0000110非00110非000101非0非011002.4.5 自增、自减运算符自增、自减运算符(1)自增(+)、自减(-)运算符为变量的增1和减1提供了紧凑格式。(2)自增、自减运算符都是单目运算符,其作用是使变量的值增1或减1。(3)自增、自减运算符有四种应用格式:int a=3;
18、b=a+;等价于 b=a;a=a+1;int a=3;b=a-;等价于 b=a;a=a-1;(运算符后置用法,代表先使用变量,然后对变量增值)int a=3;b=+a;等价于 a=a+1;b=a;int a=3;b=-a;等价于 a=a-1;b=a;(运算符前置用法,代表先对变量增值,再使用变量)(4)C+编译器在处理时尽可能多的自左向右将运算符结合在一起。例如:a+b表示为(a+)+b而不是a+(+b)。(5)在调用函数时,实参的求值顺序一般为自右向左。而不是PASCAL语言那样自左向右。例如:int a=1;printf(“%d,%d,%d”,a+,a+,a+);输出的结果为3,2,1而不
19、是1,2,3。2.4.6 条件运算符条件运算符(1)条件运算符“?:”是C+中惟一三目运算符,其形式为:表达式1?表达式2:表达式3它的运算方式为:先计算表达式1的值,如果其值为非0(真),则表达式2的值就是整个表达式的最终结果;否则表达式3的值就是整个表达式的值。常见的一个例子为:max=(ab)?a:b)上面例子定义了一个求两个数a和b中最大值,其中决定哪一个是最大值用了条件运算符。(2)条件运算符的结合性是自右向左。例如有以下条件表达式:ab?a:cd?c:d相当于ab?a:(cd?c:d)(3)条件运算符的优先级别高于赋值运算符,低于关系运算符和算术运算符。例如有:ab?a-b:b-a
20、相当于ab?(a-b):(b-a)2.4.7 位运算符位运算符(1)位(bit)是计算机中表示信息的最小单位,一般用0和1表示。一个字符在计算机中用8个位表示,8个位组成一个字节。C+语言需要将人们通常所习惯的十进制数表示为二进制、八进制或十六进制数来理解对位的操作。C+中所有的位运算符如下:(按位求反),(右移),&(按位与),(按位异或),|(按位或)。(2)位运算符是对其操作数按其二进制形式逐位进行运算,参加位运算的操作数必须为整数。2.4.8 sizeof运算符(求字节运算符)运算符(求字节运算符)(1)sizeof运算符是单目运算符,用于计算运算对象在内存中所占字节的多少,它有两种形
21、式:sizeof(类型标识符);sizeof 表达式;(2)sizeof可以接受的类型标识符很多,如sizeof(int)表示求整型数据在内存中所占字节数。例如:int a,则sizeof(a)表示求变量a在内存中所占字节数。例如:int a10,则sizeof(a)表示求数组a在内存中所占字节数。2.4.9 逗号运算符逗号运算符(1)逗号运算符用于将多个表达式连在一起,并将各表达式从左到右的顺序依次求值,但只有其最右端的表达式的结果,作为整个逗号表达式的结果。(2)逗号表达式的一般格式为:表达式1,表达式2,表达式n例如:int a=3,b=4,c=5;a+b,b+c,c+a;则先求解a+b
22、,再求解b+c,最后求解c+a,整个表达式的结果为c+a的结果。2.4.10 运算符优先级运算符优先级(1)运算符优先级决定了在表达式中各个运算符执行的先后顺序。高优先级运算符先于低优先级运算符进行运算。在优先级相同的情形下,则按从左到右的顺序进行运算。(2)当表达式中出现了括号时,会改变优先级。先计算括号中的子表达式值,再计算整个表达式的值。表2-4(见教材)列出了C+的所有运算符集,依优先级从高到低排列。(3)运算符的结合方式有两种:左结合和右结合。左结合表示运算符优先与其左边的标识符结合进行运算,如加法;右结合表示运算符优先与其右边的标识符结合,如单目运算符+、-。(4)同一优先级的优先
23、级别相同,运算次序由结合方向决定。如1*2/3,*和/的优先级别相同,其结合方向自左向右,则等价于(1*2)/3。(5)不同的运算符要求有不同的运算对象个数,单目运算符只需一个运算对象,如 i+,-a,sizeof(b)等。2.4.11 表达式表达式表达式是用于计算的式子,它由运算符、运算数和括号组成。最简单的表达式只有一个常量或变量,当表达式中有两个或多个运算符时,表达式称为复杂表达式,其中运算符执行的先后顺序由它们的优先级和结合性决定。执行表达式所规定的运算,所得到的结果值便是表达式的值。C+中由于运算符很丰富,因此表达式的种类也很多。常用的表达式有6种。1.算术表达式算术表达式由算术运算
24、符和位操作运算符组成的表达式。其表达式的值是一个数值,表达式的类型由运算符和运算数确定。例如,a+3*(b/2)就是一个算术表达式。2.逻辑表达式逻辑表达式由逻辑运算符组成的表达式。其表达式的值的类型为逻辑型,一般地,真用1表示,假用0表示。例如,!a&b|c就是一个逻辑表达式。3.关系表达式关系表达式由关系运算符组成的表达式。其表达式的值的类型为逻辑型,一般地,真用1表示,假用0表示。例如,ab!=c就是一个关系表达式。4.赋值表达式赋值表达式由赋值运算符组成的表达式。例如,已知a=b就是一个赋值表达式。5.条件表达式条件表达式由三目运算符组成的表达式。条件表达式的值取决于?号前面的表达式,
25、该表达式的值为非0时,整个表达式的值为:号前面表达式的值,否则为:号后面表达式的值。条件表达式的类型是:号前和:号后两个表达式中类型高的一个表达式的类型。例如,ab?a:b就是一个条件表达式。6.逗号表达式逗号表达式用逗号将若干个表达式连起来组成的表达式。该表达式的值是组成逗号表达式的若干个表达式中最后一个表达式的值,类型也是最后一个表达式的类型。逗号表达式计算值的顺序是从左至右逐个表达式分别计算。例如,a+3,b+4,c+5就是一个逗号表达式。2.4.12 数据类型转换数据类型转换C+中数据类型转换有两类,即隐式类型转换和显式类型转换。1.隐式类型转换隐式类型转换隐式类型转换是由编译器自动完
26、成的类型转换。当编译器遇到不同类型的数据参与同一运算时,会自动将它们转换为相同类型后再进行运算,赋值时会把所赋值的类型转换为与被赋值变量类型一样。隐式类型转换按从低到高的顺序进行,如图2-2所示。整型(int)短整型,字符型(short,char)单精度浮点型(float)双精度浮点型(double)无符号长整型(unsigned long)长整型(long)无符号整型(unsigned)图2-2 数据类型转换的顺序2.显式类型转换显式类型转换显式类型转换是由程序员显式指出的类型转换,转换形式有两种:类型名(表达式)(类型名)表达式这里的“类型名”是任何合法的C+数据类型,例如float、int等。通过类型的显式转换可以将“表达式”转换成适当的类型。例如:double f=3.6;int n=(int)f;这样n为3。