1、2018/11/19,第3章 数据类型、运算符与表达式,2018/11/19,3.1 C语言的数据类型,总览,2018/11/19,C语言中的数据,有常量和变量之分,它们分别属于上述这些类型。本章将介绍基本类型中的整型、实型、字符型三种数据,以及C语言中的部分运算符与表达式。,2018/11/19,3.2 常量和变量,3.2.1 常量 1. 概念 在程序运行过程中,其值不能被改变的量称为常量。 2. 分类 (1)整型常量;例3,-7 (2)实型常量;例3.14,-789 (3)字符常量;例a,3 (4)字符串常量;例“a”,“name” (5)符号常量(第9章,略)。常量的类型,可通过书写形式
2、来判别。,2018/11/19,2.3.2 变量 1.变量的概念以标识符为名字,在程序运行过程中,其值可以被改变的量称为变量。2.变量的两个要素 (1)变量名。每个变量都必须有一个名字变量名,变量命名遵循标识符命名规则。 (2)变量值。在程序运行过程中,变量值存储在内存中。在程序中,通过变量名来引用变量的值。,2018/11/19,.标识符命名规则 (1)有效字符:只能由字母、数字和下划线组成,且以字母或下划线开头。 (2)有效长度:随系统而异,但至少前个字符有效。如果超长,则超长部分被舍弃。 例,由于student_name和student_number的前个字符相同,有的系统认为这两个变量
3、,是一回事而不加区别。 在TC V2.0中,变量名(标识符)的有效长度为个字符,缺省值为。,2018/11/19,(3)C语言的关键字不能用作变量名。 注意:C语言对英文字母的大小敏感,即同一字母的大小写,被认为是两个不同的字符。 习惯上,变量名和函数名中的英文字母用小写,以增加可读性。 思考题:在C语言中,变量名total与变量名TOTAL、ToTaL、tOtAl等是同一个变量吗?,2018/11/19,标识符命名的良好习惯见名知意:所谓“见名知意”是指,通过变量名就知道变量值的含义。通常应选择能表示数据含义的英文单词(或缩写)作变量名,或汉语拼音字头作变量名。 例如,name/xm(姓名)
4、、sex/xb(性别)、age/nl(年龄)、salary/gz(工资)。注意:尽量避免用容易混淆的字符,如O和0, l和1,Z和2等。,2018/11/19,4. 变量的定义与初始化在语言中,要求对所有用到的变量,必须“先定义、后使用”;且称“在定义变量的同时进行赋初值的操作”为变量初始化。 (1)变量定义的一般格式 数据类型 变量名1,变量名2,; 例,float radius, length, area;(2)变量初始化的一般格式 数据类型 变量名1=初值1 , 变量名2=初值2,;例,float radius=2.5, length, area;,2018/11/19,补充(不同进制之
5、间的转换): 1. 二、八、十六进制概念: (1)二进制:每一位只有0和1两个数码,其运算规则是逢二进一。 (2)八进制:每一位由07中某一个数码表示,其运算规则是逢八进一。 (3)十六进制:每一位由0f中某一个数码表示,其运算规则是逢十六进一。用09这十个数字表示十六进制的09,用A,B,C,D,E,F这五个字母来分别表示10、11、12、13、14、15,字母不区分大小写。 从右往左数,最右为最低位,最左为最高位。,2018/11/19,2. 二、八、十六进制转换为十进制:乘法 (1)二进制转换为十进制:二进制数第0位(最右边)的权值是2的0次方,第1位的权值是2的1次方例,二进制数011
6、00100,转换为10进制为: 0*27+1*26+1*25+0*24+0*23+1*22+0*21+0*20= 1000乘以多少都是0,所以我们也可以直接跳过值为0的位:1*26+1*25+1*22=100,2018/11/19,(2)八进制转换为十进制:八进制数第0位(最右边)的权值是8的0次方,第1位的权值是8的1次方例,八进制数1507 ,转换为10进制为:1*83 + 5*82 + 0*81 + 7*80 = 839(3)十六进制转换为十进制:十六进制数第0位(最右边)的权值是16的0次方,第1位的权值是16的1次方例,十六进制数2AF5,转换为10进制为:2*163 + 10*16
7、2 + 15*161 + 5*160 =10997,2018/11/19,3.十进制转换为二、八、十六进制:除法 (1)十进制转换为二进制:把要转换的数除以2,得到商和余数,将商继续除以2,直到商为0。最后将所有余数倒序排列,得到数就是转换结果。例,十进制数6,转换为2进制为:(110)2,2018/11/19,(2)十进制转换为八进制:10进制数转换成8进制的方法,和转换为2进制的方法类似,惟一变化:除数由2变成8。 例,十进制数120转换成八进制数为(170)8(3)十进制转换为十六进制:10进制数转换成16进制的方法,和转换为2进制的方法类似,惟一变化:除数由2变成16。 例,十进制数1
8、20转换成十六进制数为(78)16,2018/11/19,4. 二进制与八、十六进制之间的转换: (1)二进制转换为十六进制:对二进制数以4位为一段(从右往左分段),分别转换为十六进制数。 1111 1101 , 1010 0101 , 1001 1011F D , A 5 , 9 B (2)十六进制转换为二进制:1位16进制数对应转换为4位2进制数。,2018/11/19,对应关系列表(仅列4位): 二进制数值 十进制值 十六进值 1111 = 8 + 4 + 2 + 1 = 15 F 1110 = 8 + 4 + 2 + 0 = 14 E 1101 = 8 + 4 + 0 + 1 = 13
9、 D 1100 = 8 + 4 + 0 + 0 = 12 C 1011 = 8 + 4 + 0 + 1 = 11 B 1010 = 8 + 0 + 2 + 0 = 10 A 1001 = 8 + 0 + 0 + 1 = 10 90001 = 0 + 0 + 0 + 1 = 1 1 0000 = 0 + 0 + 0 + 0 = 0 0,2018/11/19,(3)二进制转换为八进制:对二进制数以3位为一段(从右往左分段),分别转换为八进制数。 111 101 010 101 001 0117 5 2 5 1 3 (4)八进制转换为二进制:1位8进制数对应转换为3位2进制数。,2018/11/19
10、,3.3.1 整型常量 整型常量即整常数,在语言中可用三种形式表示:(1)十进制。例10、36。(注:数字之间不允许有空格) (2)八进制(以数字开头)。例012,代表(12)8,等于十进制的1*81+2*80=10。 (3)十六进制(以数字+小写字母x开头)。例0x100 ,代表(100)16,等于十进制的1*162+0*161+0*160=256 。,3.3 整型数据,2018/11/19,3.3.2 整型变量 补充:在3.1中介绍的C语言的基本数据类型中,除void型之外,各类型变量定义时可以带有各种“修饰前缀”,用于明确基本数据的含义,以准确地适应不同情况下的要求:有符号:signed
11、 无符号:unsigned(注:一般不带有此前缀均代表signed型,例int等价于signed int)长型: long (将数据的内存字节数增加一倍) 短型: short1.整型变量分类:(1)按其有无符号,可分为unsigned int,signed int两类;(2)按其在内存中所占字节数(或”位数“),可分为short int,long int两类(注:一般short int等价于int)。,2018/11/19,2.占用内存字节数与值域: 上述各类型整型变量占用的内存字节数,随系统而异。一般用字节表示一个int型变量,且long型(字节)int型(字节)short型(字节)。显然,
12、不同类型的整型变量,其值域不同。占用内存字节数为n的(有符号)整型变量,其值域为:-2n*8-1(2n*8-1-1);无符号整型变量的值域为:0(2n*8-1)。 例如,PC机中的一个int型变量,其值域为-22*8-1(22*8-1-1),即-3276832767;一个unsigned型变量的值域为:0(22*8-1),即065535。,2018/11/19,要求记忆:int以及short int:类型长度为2byte(16bit),值域为-32768 32767;unsigned int以及unsigned short int :类型长度为2byte(16bit),值域为0 65535;l
13、ong int:类型长度为4byte(32bit)。,2018/11/19,3.4 浮点型数据,3.4.1 浮点型常量 浮点型常量即实数,其值有两种表达形式: (1)十进制形式。例如3.14、9.8、3.、3.0。 (2)指数形式。又称“科学计数法”,格式为:E(e)。例如3.0+5=3*105等。3.4.2 浮点型变量 按其精度(即“数据的有效范围”)分为两种: (1)单精度型。类型关键字为float,一般占字节(位)、提供位有效数字。 (2)双精度型。类型关键字为double,一般占个字节、提供1516位有效数字。,2018/11/19,3.5 字符型数据,3.5.1 字符常量 1. 定义
14、 用一对单引号括起来的单个字符,称为字符常量。 例,A、等。 2.转义字符 语言允许使用一种特殊形式的字符常量,就是以反斜杠“ ”开头的转义字符。 见教材P48 表3.3。注意:如果反斜杠、单引号或双引号本身作为字符常量,必须使用转义字符:、“ 。,2018/11/19,例3.1 main() printf(“ AbbBbbCn”); 程序运行结果如下: CBA例3.2 main() printf(“She say,”This picture is beautiful!”n”); 程序运行结果如下: She say,” This picture is beautiful!”,2018/11/1
15、9,例3.3用转义字符输出可打印字符和不可打印字符。 main() printf(“x4Fx4Bx21n”); /* 等价于printf(“OK!n”); */ printf(“x15 xABn”); 程序运行结果如下: ! ,2018/11/19,3.5.2 字符变量 字符变量的类型关键字为char,一般占用1字节(8bit)内存单元;signed char的值域为-128127,unsigned char的值域为0 255 。1.变量值的存储: 字符变量用来存储字符常量。将一个字符常量存储到一个字符变量中,实际上是将该字符的ASCII码值(无符号整数)存储到内存单元中。 例, char c
16、h1, ch2; /*定义两个字符变量:ch1,ch2*/ ch1=a; ch2=b; /*给字符变量赋值*/,2018/11/19,2.特性: 字符数据在内存中存储的是字符的ASCII码 一个无符号整数,其形式与整数的存储形式一样,所以语言允许字符型数据与整型数据之间通用。 (1)一个字符型数据,既可以字符形式输出,也可以整数形式输出。 例3.4 字符变量的字符形式输出和整数形式输出。 main() char ch1,ch2; ch1=a; ch2=b; printf(“ch1=%c,ch2=%cn”,ch1,ch2); printf(“ch1=%d,ch2=%dn”,ch1,ch2); 程
17、序运行结果: ch1=a,ch2=b ch1=97,ch2=98,2018/11/19,(2)允许对字符数据进行算术运算,此时就是对它们的ASCII码值进行算术运算。例3.5 字符数据的算术运算。 main() char ch1,ch2; ch1=a; ch2=B; /*字母的大小写转换*/ printf(“ch1=%c,ch2=%cn”,ch1-32,ch2+32); 程序运行结果:ch1=A,ch2=b,2018/11/19,3.5.3 字符串常量 1.字符串常量的概念和字符串长度 字符串常量是用一对双引号括起来的若干字符序列。 字符串中字符的个数称为字符串长度。长度为0的字符串(即一个字
18、符都没有的字符串)称为空串,表示为“ ” (一对紧连的双引号)。 例如,“How do you do.”、“Good morning.”等,都是字符串常量,其长度分别为14和13(空格也是一个字符)。,2018/11/19,2.字符串的存储 C语言规定:在存储字符串常量时,由系统在字符串的末尾自动加一个0作为字符串的结束标志。 注意:在源程序中书写字符串常量时,不必加结束字符0,否则画蛇添足。 如果有一个字符串为“CHINA”,则它在内存中的实际存储如下所示:最后一个字符0是系统自动加上的,它占用字节而非字节内存空间。,2018/11/19,综上所述,字符常量A与字符串常量“A“是两回事: (
19、1)定界符不同:字符常量使用单引号,而字符串常量使用双引号; (2)长度不同:字符常量的长度固定为1,而字符串常量的长度,可以是0,也可以是某个整数; (3)存储要求不同:字符常量存储的是字符的ASCII码值,而字符串常量,除了要存储有效的字符外,还要存储一个结束标志0。,2018/11/19,3.6 算术运算符与算术表达式,1.五种基本算术运算符: +、-(减法/取负)、*、/、%(求余数)(1)关于除法运算/ C语言规定:当分子、分母均为整型数时,为两个整数相除,其商为整数,小数部分被舍弃。例如,5 / 2 = 2。 (2)关于求余数运算 要求两侧的操作数均为整型数据,否则出错。,2018
20、/11/19,2. 自增(+)、自减(-)运算符: 自增运算使单个变量的值增,自减运算使单个变量的值减。 (1)自增、自减运算符都有两种用法: 前置运算运算符放在变量之前:变量、变量; 先使变量的值增(或减),然后再以变化后的值参与其它运算,即先增减、后运算。 后置运算运算符放在变量之后:变量、变量; 变量先参与其它运算,然后再使变量的值增(或减),即先运算、后增减。,2018/11/19,例3.6 自增、自减运算符的用法与运算规则示例。 main() int x=6, y;printf(“x=%dn“,x); /*输出x的初值*/y = +x; /*前置运算*/printf(“x=%d,y=
21、%dn“,x,y); y = x-; /*后置运算*/printf(“x=%d,y=%dn“,x,y); 程序运行结果: x=6 x=7,y=7 x=6,y=7 思考题:如果将上例中“y=+x;”语句中的前置运算改为后置(y=x+;),“y=x-;”语句中的后置运算改为前置(y=-x;),程序运行结果会如何?,2018/11/19,(2)说明: 自增、自减运算,常用于循环语句中,使循环控制变量加(或减),以及指针变量中,使指针指向下(或上)一个地址。 自增、自减运算符,不能用于常量和表达式。 例如,5+、-(a+b)等都是非法的。 在表达式中,连续使同一变量进行自增或自减运算时,很容易出错,所
22、以最好避免这种用法。,2018/11/19,算术运算符的优先级别:,2018/11/19,3. 表达式和算术表达式: (1)表达式的概念用运算符和括号将运算对象(常量、变量和函数等)连接起来的、符合语言语法规则的式子,称为表达式。单个常量、变量或函数,可以看作是表达式的一种特例。(将单个常量、变量或函数构成的表达式称为简单表达式,其它表达式称之为复杂表达式。),2018/11/19,(2)算术表达式的概念 表达式中的运算符都是算术运算符。例如,3 + 6 * 9、(x + y) / 2 - 1等,都是算术表达式。4.运算符的优先级与结合性: (1)所谓结合性是指:当一个操作数两侧的运算符具有相
23、同的优先级时,该操作数是先与左边的运算符结合,还是先与右边的运算符结合。 自左至右的结合方向,称为左结合性。反之,称为右结合性。 结合性是语言的独有概念。除单目运算符、赋值运算符和条件运算符是右结合性外,其它运算符都是左结合性。,2018/11/19,(2)表达式求值 按运算符的优先级高低次序执行。例如,先乘除后加减。 如果在一个运算对象(或称操作数)两侧的运算符的优先级相同,则按语言规定的结合方向(结合性)进行。 例如,算术运算符的结合方向是“自左至右”,即:在执行“a b + c”时,变量b先与减号结合,执行“a - b”;然后再执行加c的运算。,2018/11/19,3.7 赋值运算及赋
24、值中的类型转换,1.赋值运算:“=”就是赋值运算符,它的作用是将一个表达式的值赋给一个变量。赋值运算的一般形式为: 变量 = 赋值表达式 ;例如,int x = 5,y; y = 3+x*7-6 ;注意:如果表达式值的类型与被赋值变量的类型不一致,系统自动地将表达式的值转换成被赋值变量的数据类型,然后再赋值给变量。例,main()int a=5;float b;b=a;相当于b=5.0,2018/11/19,2.复合的赋值运算符:复合赋值运算符是由赋值运算符之前再加一个双目运算符构成的。(例,+=、-=、*=、/=、%=等)复合赋值运算的一般格式为: 变量 双目运算符 = 表达式 复合赋值运算
25、符它等价于:变量 = 变量 双目运算符 (表达式)。例如,x += 3 /* 等价于x=x+3 */y *= x + 6 /* 等价于y=y*(x+6),而不是y=y*x+6 */C语言规定的10种复合赋值运算符如下:+=,-=,*=,/=,%=; /*复合算术运算符(5个)*/&=,=,|=,=; /*复合位运算符(5个)*/,2018/11/19,补充:当一个语句由多个赋值运算符串接时,运算顺序从右往左: 例,int b=5;b *= b += 4; 分析: b += 4;b=9; b *= 9;b=81;,2018/11/19,3. 赋值中的类型转换(自动转换):,补充: Turbo C
26、系统中将字符型以及整型均看作有符号类型,其最高位均看作符号位。最高位为0代表正数,最高位为1代表负数;正数在存储器中以其二进制原码存储,负数在存储器中以其二进制补码存储。对于负数,其原、补码之间的转换方法如下:原码补码:除最高位外各位均取反;末位加1。补码原码:方式同”原码补码”。快捷方法:char型:补码=256+原码(例,-2的补码为254)int型:补码=65536+原码(例,-2的补码为65534),2018/11/19,转换规则:赋值号右边的值转变为赋值号左边变量所属的类型。 分为三种情况: (1)截位:赋值号右边值的精度高于赋值号左边变量的精度,将多余位数截掉。 (2)补位:赋值号
27、右边值的精度低于赋值号左边变量的精度,将缺的位数补上。 (3)位数不变,内容不变:适合于精度相同的数据类型之间互相赋值。 (例,unsigned int short int),2018/11/19,(1)截位:又分为以下几种情况。 intchar:保留低8位,将多余的高8位截去。 例,char a=515;因为(515)10=(00000010|00000011)2高位截去后,代表a =(00000011)2,代表ASCII码为3的符号。long intint/short int:保留低16位,将多余的高16位截去。 float/doubleint:将小数部分舍去。 例,int x=36.00
28、1; 即x值为36。double float:截取前7位有效数字,结果会降低精度。 例,float d=3678.0756777; 即d值为3678.075。,2018/11/19,(2)补位:又分为以下几种情况。 整型 float/double:数值不变,但以float/double形式存入变量(即,具体在存储器中占4字节/8字节存储空间)。 例,float f=51; 则在内存中f存储的是51.00000。charint/short int/long int:unsigned char 整型:将char的具体值放入整型的低8位,不足的高位全补0。signed char 整型:将char的具
29、体值放入整型的低8位;若字符的最高位为0(代表正数),则不足的高位全补0;若字符的最高位为1(代表负数),则不足的高位全补1 。,2018/11/19,例,signed char a=¥; int i=a;因为¥的ASCII码为157=(10011101) 2,其符号位(最高位)为1,则将高8位全部补1,则i=(1111111110011101) 2(看作补码),则其原码为=(1000000001100011) 2 =-99。 int long int :将int的具体值放入long int的低16位;若int的最高位为0则不足的高位全补0;若int的最高位为1则不足的高位全补1 。,2018
30、/11/19,4.强制类型转换:数据类型强制转换的一般格式为:(要转换成的数据类型)(被转换的表达式)当被转换的表达式是一个简单表达式时,外面的一对圆括号可以缺省。 例如, (double)a (等价于(double)(a) /*将变量a的值转换成double型*/ (int)(x + y) /*将x+y的结果转换成int型*/ (float)5 / 2(等价于(float)(5)/2)/*将5转换成实型,再除以2(=2.5)*/ (float)(5 / 2) /*将5整除2的结果(2)转换成实型(2.0)*/注意:强制转换类型得到的是一个所需类型的中间量,原表达式类型并不发生变化。例如,(d
31、ouble)a 只是将变量a的值临时转换成一个double型的中间量,a的数据类型并未转换成double型。,2018/11/19,例3.7 #include “stdio.h” main()int i1,i2;float f1,f2;f1=34.25; f2=66.89;i1=(int)(f1+f2);i2=(int)f1+(int)f2;printf(“i1=%d,i2=%dn”,i1,i2);程序运行结果: i1=101,i2=100,2018/11/19,5.不同类型数据混合运算时类型转换规则(由C编译程序自动完成):整型、实型和字符型数据间可以混合运算(因为字符数据与整型数据可以通用
32、)。(1)运算步骤(方法):将运算符两边不同类型的数据先临时转换为同一类型,然后再进行运算。 (2)转换规则:由低精度类型向高精度类型转换(即“向上靠”原则),其最终类型为表达式中精度最高的类型。 (见教材P54 图3.10),2018/11/19,转换规则说明:,横向向左的箭头,表示必须的转换。char和short 型必须转换成 int 型,float型必须转换成double型。 纵向向上的箭头,表示不同类型的转换方向。 例如,int型与double型数据进行混合运算,则先将int型数据转换成double型,然后在两个同类型的数据间进行运算,结果为double型。 注意:箭头方向只表示数据类
33、型由低向高转换,不要理解为int型先转换成unsigned型,再转换成long型,最后转换成double型。,2018/11/19,例3.8求表达式30*A+12.3的值。运算步骤:A转换成为其ASCII码65(int型); 12.3转换为double型:12.30000000000000; 30*65=1950(int型); 1950转换为double型:1950.000000000000;两double型数相加:1962.300000000000;结果转换为float型:1962.300程序运行结果为:1962.300,2018/11/19,3.8 逗号运算(,)符 及其表达式,逗号运算符
34、又称顺序求值运算符。用逗号运算符“,”连接起来的式子,称为逗号表达式。1. 一般形式:表达式, 表达式, , 表达式n,2018/11/19,2. 求解过程: 自左至右,依次计算各表达式的值,“表达式n” 的值即为整个逗号表达式的值。 例,逗号表达式“a = 3 * 5, a * 4”的值为60:先求解a = 3 * 5,得a=15;再求a * 4 = 60,所以逗号表达式的值为60。 例,逗号表达式“(a = 3 * 5, a * 4), a + 5”的值为20:先求解a = 3 * 5,得a=15;再求a * 4=60(但a=15不变);最后求解a + 5=20,所以逗号表达式的值为20。 注意:并不是任何地方出现的逗号,都是逗号运算符。很多情况下,逗号仅用作分隔符。,2018/11/19,课堂练习,分别求出下列3题中x的结果值: (1) x=(a=3, a+1, a+1, a+1) (2) x=(a=3, a+, a+, a+) (3) x=(a=3, +a, +a, +a),2018/11/19,习题三,P663.6 P673.9 3.10 P683.12,