《基本数据类型、运算符与表达式.ppt》由会员分享,可在线阅读,更多相关《基本数据类型、运算符与表达式.ppt(85页珍藏版)》请在金锄头文库上搜索。
1、2基本数据类型、运算符与表达式河南理工大学C语言程序设计编写组重点、难点l本章重点:lC语言的基本数据类型l变量的定义、赋值、初始化以及使用方法l基本运算符的运算规则及优先级别l表达式的构成规则和计算l数据类型转换的意义和实质l本章难点:l数据类型的作用及注意事项l自增、自减运算符的使用l运算符优先级别l混合表达式运算l类型转换及转换过程中出现的误差内容提要l2.1 C语言的数据类型语言的数据类型l2.2常量和变量常量和变量l2.2.1常量常量l2.2.2 变量变量l2.3 整型数据整型数据l2.3.1 整型常量的表示整型常量的表示l2.3.2 整型变量整型变量l2.3.3 整型常量的类型整型
2、常量的类型l2.4 实型数据实型数据l2.4.1 实型常量的表示实型常量的表示l2.4.2 实型变量实型变量l2.4.3 实型常量的类型实型常量的类型l2.5字符型数据字符型数据l2.5.1字符型常量字符型常量l2.5.2 字符变量字符变量内容提要l2.6 算术运算符与算术表达式算术运算符与算术表达式l2.6.1 基本算术运算符基本算术运算符l2.6.2 算术表达式及算术运算符的优先级和结合性算术表达式及算术运算符的优先级和结合性l2.6.3 自增、自减运算符自增、自减运算符l2.7 赋值运算符与赋值表达式赋值运算符与赋值表达式l2.7.1 赋值运算符赋值运算符l2.7.2 复合赋值运算符复合
3、赋值运算符l2.7.3 赋值表达式赋值表达式l2.8 逗号运算符与逗号表达式逗号运算符与逗号表达式l2.9 位运算符位运算符l2.9.1 位运算符位运算符l2.9.2 位运算复合赋值运算符位运算复合赋值运算符l2.10 数据类型转换与计算类型长度运算符数据类型转换与计算类型长度运算符l2.10.1 自动类型转换自动类型转换l2.10.2 强制类型转换强制类型转换l2.10.3计算类型长度运算符计算类型长度运算符2.1 C语言的数据类型语言的数据类型l程序主要由算法和数据结构两部分组成。l所谓数据结构指的是数据的组织形式,C语言的数据结构以数据类型的形式出现。l数据类型是指数据的内部表现形式,是
4、进行C语言程序设计的基础。l数据类型可以根据数据在加工中的特征来划分。lC语言规定,在C程序中使用的每一个数据都属于惟一的一种数据类型,没有无类型的数据,一个数据也不可能同时属于多种数据类型。lC语言的数据类型可分为4大类,如图2-1所示。l1)基本类型:不可再将其分解为其他类型。l2)构造类型:构造类型是根据已定义的一个或多个数据类型用构造的方法来定义的。l3)指针类型:指针是一种特殊的又具有重要作用的数据类型,其值用来表示某个量在内存储器中的地址。l4)空类型:空类型是从语法完整性的角度给出的一种数据类型。数据类型基本类型构造类型实型整型短整型长整型单精度型整型双精度型指针类型空类型枚举类
5、型结构体类型数组类型共用体类型图2-1 C语言的数据类型字符类型l每个数据都要在内存中(个别数据可能在寄存器中)分配若干个字节,用于存放该数据。l数据占用的内存字节数称为该数据的“数据长度”。l不同类型的数据的长度是不同的,因此,在使用任何一个数据之前,必须对数据的类型加以定义,以便为其安排长度合适的内存。2.2常量和变量常量和变量l对于基本数据类型量,按其取值是否可改变又分为常量和变量两种。l在程序执行过程中,其值不发生改变的量称为常量。变量是指其值可以变化的量,变量实质上是代表了内存中某个存储单元。2.2.1常量l在C语言中,常量也称为常数,可分为4类:整型常量、实型常量、字符常量和字符串
6、常量。常量的类型由书写方法自动默认,不需要事先说明。从书写方式上,常量可以分为字面常量和符号常量两种。(1)字面常量l字面常量又称直接常量,就是日常所说的常数。由于从字面上即可直接看出它们是什么,因此称为“字面常量”。例如:整型常量:12、0、-3;实型常量:4.6、-1.23;字符常量:a、b。l(2) 符号常量l1)标识符l标识符是用户自定义的一种字符序列,用于表示程序中需要辨认的对象,比如变量、数组、函数等对象的名字。lC语言的标识符可以分为关键字、预定义标识符和用户标识符三类。l关键字是由C语言规定的具有特定含义的标识符,也称为保留字。关键字均为小写,如int、while等;l预定义标
7、识符在C语言中有特定的含义,如printf、include等;l用户标识符是由用户根据需要定义的标识符。l标识符的命名必须遵循如下规则:lC语言规定,标识符是由字母、数字和下划线组成的一串符号,但必须以英文字母或下划线开头。例如:larea、PI、_ini、a123都是合法的标识符,1se、x-x、a.a、a&b则为非法的标识符。l标识符区分大小写。例如sum、SUM和Sum是三个不同的标识符。l在定义用户标识符时除了要遵循标识符的命名规则外,还应该注意:l不允许使用关键字作为用户标识符的名字。l用户标识符命名应以直观且易于拼读为宜,即做到“见名知意”,最好使用英文单词及其组合,以便于记忆和阅
8、读。l用户标识符与预定义标识符相同时,系统并不报错,只是该预定义标识符将失去原有含义,代之以用户确定的含义,或者引发一些运行时的错误。因此建议用户标识符不要与预定义标识符相同。lANSIC没有规定标识符长度,但不同的C语言编译系统都有相应的规定,如MSC规定长度为8个字符,TurboC2.0规定为32个字符。l2)符号常量l符号常量也称宏常量,是指用一个标识符代表一个常量,其目的是为了能在程序中明确看出某些常量所表述的对象。符号常量由C语言中的宏定义预处理命令来定义。l符号常量的定义格式如下:#define符号常量常量l其中符号常量应遵循标识符的命名规则,习惯上用大写字母作为符号常量的标识符,
9、而常量可以是任何类型的。符号常量一经定义,凡在源程序中使用该符号常量时,都用其后指定的常量来替换。例2-1符号常量的使用#include#definePI3.14159#defineR5.3main()printf(area=%fn,PI*R*R);/*输出圆面积*/printf(circumference=%fn,2*PI*R);/*输出圆周长*/该程序的运行结果如下:area=88.247263circumference=33.300854复习复习复习# define 符号常量符号常量 常量常量变量l在C语言中,变量必须遵循“先定义、后使用”的原则,l变量定义语句格式如下:类型标识符类型标
10、识符 变量名变量名1,变量名变量名2,;l其中,类型标识符说明了变量的类型,如整型、实型和字符型等。变量名属用户标识符,应遵守标识符命名规则。编译时,系统根据指定的类型分配给变量若干个连续字节存储空间。l在定义变量的同时也可指出它的初值,编译系统在为变量分配存储空间时,将该初值存入这个存储空间,这种方法称为变量的初始化。格式如下: 类型标识符类型标识符 变量名变量名=初值初值;l注意:变量定义语句可放在函数外,也可放在函数或复合语句内。2.3整型数据l2.3.1整型常量的表示l整型常量就是整数,用来表示一个正的、负的或零的整数值。在C语言中,整型常量有十进制、八进制和十六进制等三种数制表示方法
11、。l1)十进制整数:与日常使用的整数写法一样。例如:0、-143、87等。l2)八进制整数:书写时,以数字0开头,后面是八进制数字序列,数字取值范围为07。例如:00、015、037等均为合法的八进制数,而0539、02A则为非法的八进制数。l3)十六进制整数:以0x或0X开头的十六进制数字序列,数字取值范围为09、af或AF。例如0x0、-0xABC、0X9fc等。注意0x中的0是数字。2.3.2整型变量l(1)整型变量的分类l整型变量用来存放整数,整型变量的基本类型为int型。若加上修饰符,可定义更多的整数数据类型。l整型变量根据表达范围可分为:基本整型(int)、短整型(shortint
12、)和长整型(longint)三种,一般微型机中,int型数据占两个字节,longint型占四个字节。l根据是否有符号可以分为:有符号型(signed)和无符号型(unsigned)两种。若未指定是否有符号,则隐含为有符号型(signed)。l两种分类方法结合起来可以将整型变量分为6种,表21列出每种数据类型所占字节数和数值范围,方括弧括起来的部分可省略。TurboC的规定与表21完全一致,但有的系统略有差别。表2-1整型变量的类型整型类型符占用字节数数值范围signed int2-3276832767 即-215(215-1)signed short int2-3276832767 即-215
13、(215-1)signed long int4-214748364822147483647 即-231(231-1)unsigned int2065535 即0(216-1)unsigned short int2065535 即0(216-1)unsigned long int404294967295 即0(232-1)1.3 算法及其描述算法及其描述l(2)整型变量的定义l在定义整型变量时,某些类型修饰符可以省略,参照表2-1。例如:inta,b,c;/*a,b,c为有符号整型变量*/longx,y;/*x,y为有符号长整型变量*/unsignedp,q;/*p,q为无符号整型变量*/l(3
14、)整型数据在内存中的存放形式l数据在内存中是以二进制形式存放的。对于有符号整型数来说,存储单元的最高位是符号位(如int型,从右向左依次为第0位、第1位,最高位指第15位),使用0表示正数,1表示负数,其余为数值位。无符号整型数没有符号位,其存储单元全部二进制位都用于存放数值,因而无符号整型变量不能存储负数。int型有符号变量和无符号变量在表示最大数时,内存的存储如图22所示。符号位signed intunsigned int01111111111111111111111111111111图22 int型有符号整型和无符号整型最大数的表示l实际上,整型数据是以补码的形式来存储的。正数的补码与原
15、码相同;对于负数来说,将原码的符号位保持不变,数值位逐位取反(变为反码),末位(即最右边的那一位)加1,即得补码。也就是说,一个负数的补码等于该负数的反码与末位加1之和。例如,求10的补码(设为2个字节),步骤如下。l写出10的原码:1000000000001010l数值位取反,得10的反码:1111111111110101l末位加1,得-10的补码:1111111111110110l有时需要将二进制的补码转换成十进制数,步骤如下(以补码1111111111110110为例)。l各数值位取反,得1000000000001001l位加1,得1000000000001010l转换为十进制,得-10
16、l即,负数的补码的补码就是原码。l4)整型数据的溢出l在TurboC中一个int型变量的最大允许值为32767,如果再加1,会出现什么情况?我们可以通过一个例子来加以说明。l例2-2整型数据的溢出main()inta,b;a=32767;b=a+1;printf(%d,%d,a,b);la和b的存储示意图如图23所示。ab1000000000000000图23 a和b的存储示意图01111111111111112.3.3整型常量的类型l整型常量也有短整型、长整型、有符号和无符号之分。在16位字长的机器上,整型常量占用2个字节的存储空间,此为短整型;而长整型常量占用4个字节的存储空间,书写时,需
17、要在整数的末尾要加上字母L或l。例如148L(十进制长整型数)、013L(八进制长整型数)、0x16L(十六进制长整型数)等。l在表示无符号整型常量时,需要在数值后添加字母U或u作为后缀。例如358u、0x38Au、235LU等都是无符号整型常量。八进制和十六进制数通常是无符号数。l注意长短整数所占的字节及不同进制的表示,如20和20L虽然有相同的数值,但在内存中却占用不同数量的字节;再如10、010、0x10等都是短整型常量,但它们却表示不同的数值。2.4实型数据l2.4.1实型常量的表示l实型常量也称浮点型常量、实数或浮点数。在C语言中,实型常量的表示采用十进制,它的书写方式有两种:l1)
18、小数形式l即数学中常用的实数形式,由数码09和小数点组成。例如,0.0、25.0、5.789、0.13、5.0、300.、-267.8230等均为合法的实数。注意,必须有小数点。l2)指数形式l指数形式也称为科学记数法,由尾数、阶码标志“e”或“E”以及阶码(只能为整数,可以带符号)组成。l例如,2.1E5(等于2.1105),3.7E-2(等于3.710-2),0.5E7(等于0.5107),-2.8E-2(等于-2.810-2)都是合法的;而345(无小数点),E7(阶码标志E之前无数字),-5(无阶码标志),53.-E3(负号位置不对),2.7E(无阶码)都不是合法的实型数。l需要注意的
19、是,采用指数形式表示实型常量时,在字母e或E的前后及数字之间不能插入空格。2.4.2实型变量l(1)实型变量的分类l实型变量又称浮点变量,用来存放实型数。实型变量分为单精度(float)、双精度(double)和长双精度型(longdouble)三种类型。但ANSIC并未规定每种类型数据的长度、精度和数值范围。表2-2列出微机上常用的C编译系统的情况,不同的编译系统会有差异。(2)用流程图描述算法表2-2 实型变量的数据类型类型标识符比特数有效数字数的范围float3267-3.4E+38 3.4E+38double641516-1.7E+308 1.7E+308long double1281
20、819-1.2E+4932 1.2E+4932l(2)实型变量的定义floata=1.5,b=0.35,c;/*定义a、b、c单精度实型变量,并对a、b初始化*/doublex,y,z;l(3)实型数据在内存中的存放形式与整型数据的存储方式不同,实型变量是按照指数形式存储的。系统将实型数据分为小数部分和指数部分,分别存放。例如实数31.4159,在内存中的存放形式如图24所示。例1-3的流程图l(4)实型变量的舍入误差由于实型变量是用有限的存储单元存储的,因此提供的有效数字是有限的,在有效位以外的数字将被舍去,由此可能会产生一些误差。l例2-3实型变量的舍入误差。main()floata,b;
21、a=123456.789e5;b=a+20;printf(a=%fn,a);printf(b=%fn,b);由于a是单精度浮点型,其有效数字为7位,后面的数字是无意义的数字。因而把20加在后几位上,是无意义的。故本例程序运行的结果是:a=12345678848.000000b=12345678848.0000002.4.3实型常量的类型lC编译系统将实型常量当作双精度来处理。l如果要指定一个实型常量为单精度型,可在其后加后缀f或F作为单精度数来处理。l例如,4.5E1F、-4.5E-2F等。2.5字符型数据字符型数据l2.5.1字符型常量l(1)字符常量lC语言中,用单引号括起来的一个字符称为
22、字符常量。例如,a、b、=、+、?等都是字符常量。l在内存中,每个字符常量都占用一个字节,具体存放的是该字符对应的ASCII代码值。如a、A、1在内存的字节中存放的分别是十进制整数97、65和49。因此在C语言中,一个字符常量可以看成是“整型常量”,其值就是ASCII代码值,例如:a+5、A-5、1+10分别等于整数值102、60、59。l在语言中,字符常量有以下特点:l字符常量只能用单引号括起来,不能用双引号或其它括号。l字符常量只能是单个字符,因此abc是非法的。lC语言规定,字母是区分大小写的,所以a和A是不同的字符常量。l(2)转义字符l把字符放在一对单引号的做法,适合于多数可打印字符
23、,但是某些控制字符(如回车符、换行符等)和一些ASCII字符却无法使用字符常量进行表示。因此,C语言中引入了一种特殊形式的字符常量转义字符。转义字符以反斜线“”开头,后跟一个或几个字符。因为此形式将反斜杠后面的字符赋予了新的含义,故称“转义”字符。常用的转义字符及其含义如表2-3所示。表2-3常用的转义字符及其含义常用的转义字符及其含义转义字符转义字符的意义n换行t横向跳到下一制表位置(代表Tab键)b退格r回车v竖向跳格f走纸换页反斜杠符“”单引号字符双引号字符a鸣铃ddd13位八进制数所代表的字符xhh12位十六进制数所代表的字符(3)字符串常量l字符串常量是由一对双引号括起的字符序列。例
24、如,CHINA,Cprogram,12365478等都是合法的字符串常量。l前面介绍的转义字符也可以出现在字符串中,例如,ABCD、101102x34x44等都是字符串,分别表示“ABCD”、“ABCD”两个字符串。要特别注意双引号是字符串的定界标符,所以在字符串中使用双引号必须使用转义字符“”。例如:ABCD是表示“ABCD”这一串字符的。字符串常量和字符常量的区别:l字符常量由单引号括起来,字符串常量由双引号括起来。l字符常量只能是单个字符,字符串常量可以为空字符串,也可以含一个或多个字符。l可以把一个字符常量赋予一个字符变量,由于在语言中没有字符串变量,因而不能把一个字符串常量赋予一个字
25、符串变量。但可以用一个字符数组来存放一个字符串常量(参见第6章)。l字符常量占一个字节的内存空间。字符串常量占的内存字节数等于字符串中字符数加1,增加的一个字节由系统自动存入字符0(ASCII码为0),作为字符串结束的标志。2.5.2字符变量l字符变量用于存放单个字符常量,使用关键字char来定义。l例如:lcharc1=x,c2=y,c3;lcharoptr;l由于字符的值是以ASCII码的形式存放,所以可以把字符变量看成是整型变量。C语言允许对整型变量赋以字符值,也允许对字符变量赋以整型值。l在格式化输出时,允许把字符变量按整型变量输出,也允许把整型变量按字符变量输出。整型变量为二字节变量
26、,字符变量为单字节量,当整型量按字符型量处理时,只有低八位字节参与处理。例2-4字符变量的值main()chara=97,b=98;printf(%c,%cn%d,%dn,a,b,a,b);l上面程序中,a、b为字符型变量,但在赋值语句中赋予整型值。a、b值的输出形式取决于printf函数格式中的格式控制符;当格式控制符为%c时,输出的变量值为字符,当格式控制符为%d时,对应输出的变量值为整数,l程序运行的结果为:a,b97,982.6 算术运算符与算术表达式算术运算符与算术表达式l运算是对数据的处理操作,参加运算的数据称为运算对象(也称运算量或操作数),运算对象可以是常量、变量、函数或表达式
27、。l标识运算的符号称为运算符,若按运算时运算对象的个数可分为单目运算符(单目运算是指对一个操作数进行操作)、双目运算符、三目运算符等几类。用运算符和括号把运算量连接起来的、符合C语言语法规则的式子称为运算表达式。凡是表达式都有一个值,即运算结果。2.6.1基本算术运算符l基本算术运算符是对数据进行简单算术运算的,共有+(加)、-(减)、*(乘)、/(除)、%(求余)等5个。这些运算符都为双目运算符。在使用基本算术运算符应注意以下几点:l加(+)、减(-)、乘(*)运算和普通运算中的加法、减法和乘法相同。例如,2.1+3.6的结果是5.7;2.1*3的结果是6.3。l如果双目运算符两边的运算对象
28、的类型不一致,如一边是整型,另一边是实型时,系统自动把整型数据转化为实型数据,使运算符两边的类型达到一致后,再进行运算,其转换规律见本章后续内容。l双目除运算的结果与运算对象的数据类型有关。当两个整数相除时,其结果为整数。如14/5的结果为2。l使用求余运算符(%)时,要求运算符两边运算量必须为整型。在运算符左侧的运算量为被除数,右侧的运算量为除数,运算结果是两数相除后所得的余数。在TurboC中,所得结果的符号与被除数相同。例如17%-3的结果为2,-19%4的结果为-3。lC语言中,所有实型数的运算均以双精度方式进行。若是单精度,则在尾数部分补0,使之转化为双精度数。l正负号运算符为+(正
29、号)和-(负号)时,它们为单目运算符。2.6.2算术表达式及算术运算符的优先级和结合性l(1)算术表达式l用算术运算符将运算对象连接起来的表达式称为算术表达式。一个表达式有一个值及其类型,它们等于计算表达式所得结果的值和类型。l以下是算术表达式的例子:la+bl(a*2)cl(x+r)*8-(a+b)7l在C语言中,算术表达式求值规律与数学中的四则运算的规律类似,其运算规则和要求如下:l在表达式中,可使用多层圆括号,但左右括号必须配对,运算时从内层圆括号开始,由内向外以此计算表达式的值。l在算术表达式中,若包括不同优先级的运算符,则按运算符的优先级别由高到低进行,若表达式中运算符的级别相同,则
30、按运算符的结合方向进行。l(2)算术运算符的优先级lC语言规定了运算符的优先级和结合性。当表达式中出现多个运算符时,就会碰到哪个先算,哪个后算的问题,这个问题称为运算符的优先级。若一个运算对象两侧有不同的运算符,应先执行“优先级别”高的运算,例如先乘除后加减。表达式a-b*c,b的左侧为减号,右侧为乘号,乘号的优先级高于减号,因此相当于a-(b*c)。l(3)算术运算符的结合性l如果在一个运算对象的两侧有两个优先级相同的运算符,则按结合方向顺序处理。语言中各运算符的结合方向有两种,即自左至右(称为左结合性)和自右至左(称为右结合性)。同级单目算术运算符的结合性是自右向左,同级双目算术运算符的结
31、合性是自左向右。例如,在计算表达式x-y+z时,y先与“-”号结合,执行x-y运算,然后再执行+z的运算。有些运算符的结合方向为“自右至左”,即右结合性(例如,赋值运算符,具体例子在后面介绍)。基本算术运算符的运算对象、运算规则、运算结果及结合性如表2-4所示。表2-4基本算术运算符对象数优先级名称运算符运算规则运算对象结合性单目1正+取原值整型或实型自右向左负-取负值双目2乘*乘法自左向右除/除法模%整除取余整型3加+加法整型或实型减-减法2.6.3自增、自减运算符l自增运算符“+”和自减运算符“-”都是单目运算符,自右向左结合,作用是使变量的值增1或减1,结果再存回原变量。它们既可以作前缀
32、运算符(位于运算对象的前面),例如+x和-x,也可以作后缀运算符(位于运算对象的后面),例如x+和x-。l在只需对变量本身进行加1或减1而不考虑表达式值的情况下,前缀运算和后缀运算的效果完全相同,否则,结果是有区别的。(1)+i,-i在使用在使用i之前,先使之前,先使i的值加的值加1或减或减1(2)i+,i-在使用在使用i之后,使之后,使i的值加的值加1或减或减1 即:先使用运算对象,后对运算对象加即:先使用运算对象,后对运算对象加1或减或减1 请思考下列程序的输出结果l#include“stdio.h”lmain()linti=0,j;lj=i+;lprintf(“%d%dn”,i,j);l
33、i=0;lj=+I;lprintf(“%d%dn”,i,j);l例2-5自增、自减运算符的使用。main()inti=5,x;x=i+;/*后缀运算,先把i的值赋给x,然后i的值加1*/printf(i=%d,x=%dn,i,x);/*i的值为6,x的值为5*/printf(%dt,+i);/*前缀运算,先把i的值加1,然后输出i*/printf(%dt,-i);/*表达式-i的值为6*/printf(%dt,i-);/*表达式i-的值为6*/printf(%dt,-i+);printf(%dn,-i-);程序运行结果如下:i=6,x=5766-5-6使用自增、自减运算符时应注意:l自增、自减
34、运算符含有赋值的功能,其运算对象可以是整型、实型、字符型、指针型变量或数组元素,但不能是常量和表达式,因为不能给常量或表达式赋值。lC语言规定,当出现难以区分的若干个+或-组成运算符串时,自左向右取尽可能多的符号组成运算符。如i+j应理解为(i+)+j,而不是i+(+j)。l不要在一个表达式中对同一个变量进行多次诸如i+或+i等运算,例如写成:i+*+i+i-*-i,这种表达式不仅可读性差,而且不同的编译系统对这样的表达式将作不同的解释,因而所得结果也各不相同。2.7 赋值运算符与赋值表达式赋值运算符与赋值表达式l2.7.1赋值运算符l赋值运算符“=”是双目运算符,其左边必须是变量,右边是表达
35、式。赋值运算符的功能是先求出右边表达式的值,然后把此值赋给左边的变量。确切的说,是把数据放入该变量为标识的存储单元中去,将原有的数据替换掉。例如,若a和b都被定义成int型变量la=50/*把常量50赋给变量a*/lb=a/*把a中的值赋给变量b,a中的值不变*/使用赋值运算符应注意以下几点:l赋值运算符具有自右向左的结合性,其优先级只高于逗号运算符,比任何其他运算符的优先级都低。例如:表达式a=b=c=9,c的两边都是赋值运算符,赋值运算符的结合为“自右至左”的,即右结合性。根据自右至左的原则,相当于对表达式a=(b=(c=9)进行运算。l赋值运算符不同于数学中的“等于号”,这里不是等同的关
36、系,而是进行“赋予”的操作。因此对于表达式n=n+1来说,它不是一个合法的数学表达式,但是一个合法的赋值表达式,其作用是取变量n中的值加1后再放入到变量n中。l赋值运算符的左侧只能是变量而不能是常量或表达式。如a=7+1=b则不是合法的赋值表达式。2.7.2复合赋值运算符l在赋值运算符之前加上其他运算符可以构成复合赋值运算符。C语言规定可以使用10种复合赋值运算符,分为算术复合赋值和位运算复合赋值。复合赋值运算符的优先级与简单赋值运算符的优先级相同,且结合方向也是自右向左。算术复合赋值运算符的运算对象、运算规则与结果如表2-5所示,位运算复合赋值后面介绍。表2-5算术复合赋值运算符对象数名称运
37、算符运算规则运算对象运算结果双目加赋值+=a+=b*3相当a=a+(b*3)数值型数值型减赋值-=a-=b+5相当a=a-(b+5)乘赋值*=a*=b+7相当a=a*(b+7)除赋值/=a/=b+9相当a=a/(b+9)模赋值%=a%=b+2相当a=a%(b+2)整型整型2.7.3赋值表达式l由赋值运算符将一个变量和一个表达式连接起来的式子称为赋值表达式。赋值运算符具有右结合性。因此la=b-=c+=5l可理解为la=(b-=(c+=5)l再例如,式子:lx=(a=5)+(b=8)l是合法的。它的意义是把5赋予a,8赋予b,再把a,b相加,和赋予x,故x等于13。2.8 逗号运算符与逗号表达式
38、逗号运算符与逗号表达式l在C语言中,“,”称为逗号运算符,其功能是把两个或多个表达式连接起来,组成一个表达式,称为逗号表达式。其形式如下:l,l逗号表达式的结合性为从左到右,即先计算表达式1,再计算表达式2,最后计算表达式n。最后一个表达式的值就是逗号表达式的值。l逗号优先级在所有运算符中是最低的。例2-6逗号运算符。main()intx,a;x=(a=3,6*3);printf(a=%d,x=%dn,a,x);x=a=3,6*a;printf(a=%d,x=%dn,a,x);l表达式x=(a=3,6*3)中,x的值等于表达式6*3的值;在表达式x=a=3,6*a中,由于逗号运算符的优先级最低
39、,因此x的值应等于a的值,都为3。程序运行的结果应为:a=3,x=18a=3,x=32.9 位运算符位运算符l2.9.1位运算符l位运算是一种对运算对象按二进制位进行操作的运算。位运算不允许只操作其中的某一位,而是对整个二进制位进行操作。在C语言中,位运算的对象只能是整型或字符型数据,不能是其他类型的数据,其运算结果仍是整型或字符型数据。(1)“按位取反”运算l运算符是位运算中唯一的一个单目运算符,运算对象在运算符的右边,具有右结合性。其功能是对运算对象的各二进位按位求反,即使每一位上的0变1;变1为0。l例如9的运算结果为-10,即将9的二进制0000000000001001按位求反后为:1
40、111111111110110,这是补码表示,转换为原码,写成十进制,就是-10。(2)“左移”运算l左移运算符“”是双目运算符。运算符左边是移位对象,右边是整型表达式,代表左移的位数。其功能把“”左边的运算数的各二进位全部左移若干位,左移时,右端(低位)补0,左端(高位)移出的位数丢失,即高位丢弃,低位补0。l例如:a”是双目运算符。其功能是把“”左边运算对象的各二进位全部右移若干位,“”右边的整形表达式指定移动的位数。l例如:l设inta=15,b;lb=a2l表示把0000000000001111中每位二进制数右移两位,其结果为0000000000000011(十进制3)(注意a的值并没
41、有改变)。l应该说明的是,对于有符号数,在右移时,符号位将随同移动。当为无符号整数或正整数时,最高位补0;而为负数时,最高位位补1。(4)“按位与”运算l按位与运算符“&”是双目运算符。其功能是参与运算的两个运算对象各对应的二进位分别进行“与”运算。只有对应的两个二进位均为1时,结果位才为1,否则为0。参与运算的数以补码方式出现。l例如:9&(-5)可写算式如下:l0000000000001001(9的二进制补码)l&1111111111111011(-5的二进制补码)l0000000000001001(9的二进制补码)l可见9&(-5)=9。l按位与运算通常用来对某些位清0或保留某些位。例如
42、把a的高八位清0,保留低八位,可作a&255运算(255的二进制数为0000000011111111)。(5)“按位异或”运算l按位异或运算符“”是双目运算符。其功能是参与运算的两个运算对象各对应的二进位相异或,当两对应的二进位相同时,则该位的结果为0;数不同,则该位的结果为1。参与运算数仍以补码出现,例如95可写成算式如下:l00001001l00000101l00001100(十进制为12)(6)“按位或”运算l按位或运算符“|”是双目运算符。其功能是参与运算的运算对象各对应的二进位相或。只要对应的二个二进位有一个为1时,结果位就为1。参与运算的两个数均以补码出现。l例如:9|5可写算式如
43、下:l00001001l|00000101l00001101(十进制为13)可见9|5=13l需要说明的是,当两个运算对象类型不同时位数亦会不同。遇到这种情况,系统会进行如下处理:l先将两个运算对象右端对齐。l再将位数短的一个运算对象往高位扩充,即:无符号数和正整数左侧用0补全;负数左侧用1补全;然后对位数相等的这两个运算对象,按位进行位运算。2.9.2位运算复合赋值运算符l前面所介绍的五种双目位运算符与赋值运算符结合可以组成扩展的位运算符合赋值运算符,其表示形式及含义如表2-6所示。表2-6 位运算赋值运算符及含义运算符表达式等价的表达式=a=2a=a=b=nb=bn&=a&=ba=a&b=
44、a=ba=ab|=a|=ba=a|b2.10 数据类型转换与计算类型长度运算符数据类型转换与计算类型长度运算符lC语言允许参加运算数据值的类型相互转换,转换的方法有两种:自动类型转换和强制类型转换。l2.10.1自动类型转换l当不同类型的数据在表达式中进行混合运算时,首先它们要先转换成同一类型,然后进行运算,转换由编译系统自动完成。l(1)算术转换l当自动转换用于算术运算(加、减、乘、除、取余及负号运算)时可称之为算术转换。l转换的原则是:自动将精度低、表示范围小的运算对象类型向精度高、表示范围大的运算对象类型转,以便得到较高精度的运算结果。l具体转换规则如图25所示。doublefloatl
45、ongunsignedchar,shortint高低高图2-5 转换规则l说明:l图中横向向左指的箭头为必定转换的类型,即将表达式中的char或short全部自动转换为相应的int型;将float转换为double型。l图中纵向的箭头表示当一个运算符两端的运算对象类型不一致时,按低级别数据类型指向高级别数据类型转换的原则进行转换,以保证不降低精度。同时,纵向箭头的方向仅表示数据类型级别的高低,而并不表示需要逐级转换。l例如,有下面表达式lA+(y5)*9/xl其中x为float型,y为double型,计算时类型自动转换过程如下。l将整型5转换为double型,然后减法运算,结果为double型
46、;l将整型9转换为double型后进行乘法运算,结果为double型;l将x转换为double型后进行除法运算,结果为double型;l将A转换为double型后进行加法运算,最后结果为double型;(2)赋值转换l在赋值运算中,只有在赋值号右侧表达式的类型与左侧变量类型完全一样时,赋值操作才能进行。如果赋值运算符两侧的数据类型不一致,系统自动先把右侧表达式求得的数值按赋值号左边变量的类型进行转换,然后再赋值,l赋值转换具有强制性,如果右边表达式的数据类型长度比左边长,将丢失一部分数据,这样会降低精度,丢失的部分按四舍五入向前舍入。赋值转换l1、实型数据(包括单、双精度)l赋给整型变量时,舍
47、弃实数的小数部分l2、整型数据赋给单、双精度变量时,l数值不变,但以浮点数形式存储到变量l中l3、长度相同的有符号与无符号整型数间,原样赋值(但数值有时会有变化)l4、charintlong等类型的转换l(1)“短”数据赋给“长”变量l符号扩展:若最高位为1(负数),则变量高字节位全补1;反之,补0l(2)“长”数据赋给“短”变量l只将数据的低字节原封不动送到变量中(数据可能有差错)l自动转换规则:自动转换规则: 运算转换:不同类型数据混合运算时运算转换:不同类型数据混合运算时,向高向高看齐看齐 赋值转换:把一个值赋给与其类型不同的变赋值转换:把一个值赋给与其类型不同的变量时,量时,向左看齐向
48、左看齐 输出转换:输出时转换成指定的输出格式,输出转换:输出时转换成指定的输出格式,按规定办事按规定办事 函数调用转换:实参与形参类型不一致时转函数调用转换:实参与形参类型不一致时转换,换,各取所需各取所需例2-7赋值转换的误差。main()floatPI=3.14159;ints,r=6;s=r*r*PI;printf(s=%dn,s);l由于PI为实型;s,r为整型。在执行s=r*r*PI语句时,r和PI都转换成double型计算,结果也为double型。但由于s为整型,故赋值结果仍为整型,舍去了小数部分。因而程序执行的结果如下:s=1132.10.2强制类型转换l强制类型转换是由程序员通
49、过类型标识符实现的,通过强制类型转换可以将一种类型的变量强制转换为另一种类型。其形式为:l(类型标识符类型标识符) (表达式表达式)l其功能是把表达式的运算结果强制转换成类型标识符所表示的类型。l在使用强制转换时应注意以下几点:l1)类型标识符和表达式都必须加括号(单个变量可以不加括号),如把(int)(x+y)写成(int)x+y,则成了把x转换成int型之后再与y相加了。l2)无论是强制转换还是自动转换,都是为了本次运算的需要而对变量的数据长度进行临时性转换,而不改变该变量定义时的类型。例2-8强制转换不改变变量定义的类型。lmain()floatf=5.75;printf(int)f=%
50、d,f=%fn,(int)f,f);l(int)f是指取出f中的数据,然后转换为int型,而f的值并不改变。即(int)f的值为5(删去了小数),而f的值仍为5.75。因此程序的执行结果如下:(int)f5,f=5.7500002.10.3计算类型长度运算符l计算类型长度运算符是C语言提供用于测定某一种类型数据所占存储空间长度的运算符。计算类型长度运算符是单目运算符,其运算对象可以是任何数据类型的变量以及表达式。其格式如下:lsizeof(运算对象)(运算对象)例2-9计算类型长度运算符的使用。main()inta;floatb;printf(char:%dbyten,sizeof(char);printf(int:%dbyten,sizeof(int);printf(a:%dbyten,sizeof(a);printf(b:%dbyten,sizeof(b);程序运行结果如下:char:1byteint:2bytea:2byteb:4byte谢谢!祝读者学习快乐!河南理工大学C语言程序设计编写组