第02章数据类型、运算符和表达式

上传人:博****1 文档编号:578914079 上传时间:2024-08-25 格式:PPT 页数:110 大小:2.27MB
返回 下载 相关 举报
第02章数据类型、运算符和表达式_第1页
第1页 / 共110页
第02章数据类型、运算符和表达式_第2页
第2页 / 共110页
第02章数据类型、运算符和表达式_第3页
第3页 / 共110页
第02章数据类型、运算符和表达式_第4页
第4页 / 共110页
第02章数据类型、运算符和表达式_第5页
第5页 / 共110页
点击查看更多>>
资源描述

《第02章数据类型、运算符和表达式》由会员分享,可在线阅读,更多相关《第02章数据类型、运算符和表达式(110页珍藏版)》请在金锄头文库上搜索。

1、第二章第二章 C C的数据类型的数据类型 常量与变量常量与变量 算术运算符和算术表达式算术运算符和算术表达式 各种数值类型数据间的转换和运算各种数值类型数据间的转换和运算 赋值运算符和赋值表达式赋值运算符和赋值表达式 位运算位运算 l l 本章教学要点本章教学要点2.1 2.1 C C的数据类型的数据类型2.2 2.2 常量与变量常量与变量2.3 2.3 整型数据整型数据2.4 2.4 实型数据实型数据 2.5 2.5 字符型数据字符型数据 l主要内容主要内容2.6 2.6 变量初始化和变量赋初值变量初始化和变量赋初值 2.7 2.7 算术运算符和算术表达式算术运算符和算术表达式2.8 2.8

2、 各种数值类型数据间的转换和运算各种数值类型数据间的转换和运算2.9 2.9 赋值运算符和赋值表达式赋值运算符和赋值表达式2.10 2.10 位运算位运算 2.11 2.11 逗号运算符和逗号表达式逗号运算符和逗号表达式 l主要内容主要内容5 2.1 2.1 C C的数据类型的数据类型 C C语言提供了以下一些数据类型。给变量定义数据类型,语言提供了以下一些数据类型。给变量定义数据类型,实际上是为数据在内存中分配规定的存储空间,存储空间实际上是为数据在内存中分配规定的存储空间,存储空间通常用字节数的形式表示。通常用字节数的形式表示。 数据类型数据类型数据类型数据类型构造类型构造类型构造类型构造

3、类型指针类型指针类型指针类型指针类型空类型空类型空类型空类型 voidvoidvoidvoid枚举类型枚举类型枚举类型枚举类型 enumenumenumenum数组类型数组类型数组类型数组类型结构体类型结构体类型结构体类型结构体类型 structstructstructstruct共用体类型共用体类型共用体类型共用体类型 unionunionunionunion基本类型基本类型基本类型基本类型整型整型整型整型 intintintint字符型字符型字符型字符型 charcharcharchar实型(浮点型)实型(浮点型)实型(浮点型)实型(浮点型)单精度单精度单精度单精度floatfloatfl

4、oatfloat双精度双精度双精度双精度 doubledouble6C C数数据据类类型型基本类型基本类型指针类型指针类型字符型字符型枚举类型枚举类型整型整型浮点型浮点型数组数组结构体结构体共用体共用体有符号有符号无符号无符号有符号字节有符号字节( (符符) )型型有符号短整型有符号短整型有符号整型有符号整型有符号长整型有符号长整型有符号长长整型有符号长长整型无符号字节无符号字节( (符符) )型型无符号短整型无符号短整型无符号整型无符号整型无符号长整型无符号长整型无符号长长整型无符号长长整型单精度单精度双精度双精度长实型长实型派生类型派生类型空空类类型型72.2 2.2 常量与变量常量与变量

5、3.2.1常量和符号常量常量和符号常量n在程序运行过程中在程序运行过程中, ,其值不能被改变的量称为常量。常量区其值不能被改变的量称为常量。常量区分为不同的类型:例如分为不同的类型:例如整型整型 100 100,125125,-100-100,0 0实型实型 3.14 3.14 , 0.125 0.125,-3.789-3.789字符型字符型 a a, , b b,2 2字符串字符串 a a, , a ab b,12321232n符号常量符号常量: : 用一个标识符代表一个常量。符号常量的值用一个标识符代表一个常量。符号常量的值在其作用域内不能改变在其作用域内不能改变, ,也不能再被赋值。也不

6、能再被赋值。8例例2.1定义一个符号常量定义一个符号常量PI,表示圆周率。然后使用符号常量表示圆周率。然后使用符号常量PI计计算圆的周长。算圆的周长。# include # define PI 3.14 /*定义符号常量定义符号常量PI,表示表示3.14*/void main()float r,l;r=5.0;l = 2*r*PI;printf(l=%fn”,l );程序运行结果为:程序运行结果为:l=31.400000说明:说明:说明:说明: 程序中用程序中用# #definedefine命令行定义命令行定义PIPI代表常量代表常量3.14,3.14,此后凡在本文件中出此后凡在本文件中出现的

7、现的PIPI都代表都代表3.14,3.14,可以和常量一样进行运算可以和常量一样进行运算说明:说明:说明:说明:如再用赋值语句给如再用赋值语句给PIPI赋值是错的赋值是错的 如:如: PI=40;PI=40;/* /* 错误,不能给符号常量赋值错误,不能给符号常量赋值2.2 2.2 常量与变量常量与变量9常量常量n常量常量就是一个确知的量。程序设计语言中还可以狭义地理解为编译时能够确定,运行时不能修改的量。C语言是强类型语言,任何对象都必须有明确的类型,常量也不例外。C语言中的常量分整型常量、浮点型常量、字符常量和枚举常量四类。10整形常量整形常量3.3.1整型常量的表示方法整型常量的表示方法

8、 整型常量即整常数。在语言中,整常数可用以下三种整型常量即整常数。在语言中,整常数可用以下三种形式表示:形式表示:(1)(1)十进制整数。十进制整数。 如:如:123, -456.4123, -456.4,3.14159263.1415926。(2)(2)八进制整数。以八进制整数。以0 0头的数是八进制数。头的数是八进制数。 如:如:01230123表示八进制数表示八进制数123123,等于十进制数,等于十进制数83, -01183, -011表表示八进制数示八进制数-11,-11,即十进制数即十进制数-9-9。(3)(3)十六进制整数。以十六进制整数。以0 0x x开头的数是开头的数是161

9、6进制数。进制数。 如:如:0 0x123x123,代表代表1616进制数进制数123,123,等于十进制数等于十进制数 291 291。 -0 -0x12x12等于十进制数等于十进制数1818。11浮点型常量浮点型常量nC89规定,浮点常量只能使用十进制。n浮点数的书写可以直接书写或采用指数形式。采用指数形式时以10底数,用e/E表示指数。n指数部分必须为整数,不能是小数,不能带小数点。n指数部分的+可以省略,默认为正,。n浮点常量的默认类型是double型,但是,和整型常量一样也可以通过添加后缀来改变浮点常量的类型:nf/F:表示该浮点常量为float型。nl/L:表示该浮点常量为long

10、 double型。12字符型常量字符型常量n字符常量字符常量就是用单引号 括起来的一个字符或一个转义字符序列。例如:a、A、?、$、a、n等等。n转义字符序列转义字符序列以反斜杠打头,其后跟一个字母或13位的八进制数或x(不是0x)加12位的十六进制数,用来表示某种特殊的含义,如代表另外一个字符或某个动作等。13字符串常量字符串常量n字符串常量字符串常量就是用双引号括起来的字符序列,又称为字符串字面量,常简称为字符串。n凡是用双引号括起来的,不管里面有多少个字符,都称为字符串。n字符串以0作为结束标志,字符串中间不能含有该字符。例如,上例中的”a”,在内存中实际存放的是97(a的ASCII码)

11、和0。再如下例将得不到预期的结果。14字符串常量字符串常量n凡是用双引号括起来的,不管里面有多少个字符,都称为字符串。n字符串以0作为结束标志,字符串中间不能含有该字符。例如,上例中的”a”,在内存中实际存放的是97(a的ASCII码)和0。再如下例将得不到预期的结果。15变量变量n就象算术运算中我们可以定义一个符号来代表一个未知数一样,C语言中也可以定义一个合法的标志符来代表一个数据,称为变量变量。该标识符实际对应一块内存区域,数据就存放在该内存区域中,CPU可以读取该内存区域中的数据(即读),也可以在该内存区域上存入新的数据(即写)。命名变量的标志符必须满足标识符命名规则。16变量变量2.

12、2.2变量变量n变量代表内存中具有特定属性的一个存储单元,它用来存放变量代表内存中具有特定属性的一个存储单元,它用来存放数据,这就是变量的值,在程序运行期间,这些值是可以改数据,这就是变量的值,在程序运行期间,这些值是可以改变的。变的。n变量名实际上是一个以一个名字对应代表一个地址,在对程变量名实际上是一个以一个名字对应代表一个地址,在对程序编译连接时由编译系统给每一个变量名分配对应的内存地序编译连接时由编译系统给每一个变量名分配对应的内存地址。从变量中取值,实际上是通过变量名找到相应的内存地址。从变量中取值,实际上是通过变量名找到相应的内存地址,从该存储单元中读取数据。址,从该存储单元中读取

13、数据。172.2常量与变量常量与变量 变量名必须是标识符变量名必须是标识符例:例:sum,_total,month,Stu_name,l_1_2,BC235M.D.John,¥123,3D64,ab 注意:注意:注意:注意:n编译系统将大写字母和小写字母认为是两个不同的字符。编译系统将大写字母和小写字母认为是两个不同的字符。 n在在C C语言中,要求对所有用到的变量作强制定义,也就是语言中,要求对所有用到的变量作强制定义,也就是“先定义,后先定义,后使用使用”,凡未被事先定义的,凡未被事先定义的,C C编译系统不把它认作变量名,这就能保编译系统不把它认作变量名,这就能保证程序中变量名使用得正确

14、。证程序中变量名使用得正确。 n在选择变量名和其它标识符时,应注意做到在选择变量名和其它标识符时,应注意做到“见名知意见名知意”,即选有含意,即选有含意的英文单词的英文单词 (或其缩写)作标识符。(或其缩写)作标识符。n每一个变量被指定为一个确定类型,在编译时就能为其分配相应的存储每一个变量被指定为一个确定类型,在编译时就能为其分配相应的存储单元。单元。18例例【例2-7】变量的定义及赋值。int x = 10;int main()int y;y = x;return 0; 上例中定义了一个全局变量x和一个局部变量y,x的初始值为10,主函数中把x的值赋给y。19声明声明类型修饰存储类类型 变

15、量列表【例2-8】声明变量int age, hight, weight;/ 三个int型变量。unsigned short int age; / age为unsigned short int类型。const volatile char in_buffer;/ 字符变量static float tmp; / 静态的float型变量。202.3.2整型变量整型变量 1. 1. 整型数据在内存中的存放形式整型数据在内存中的存放形式 数据在内存中是以二进制形式存放的。数据在内存中是以二进制形式存放的。 如如: : int i; /* int i; /* 定义为整型变量定义为整型变量 */ */ i=1

16、7; /* i=17; /* 给给i i赋以整数赋以整数17 */ 17 */ 2.3整型数据整型数据注意:注意:注意:注意:n十进制数十进制数1717的二进制形式为的二进制形式为1000110001,Turbo C+ 3.0Turbo C+ 3.0为一个为一个整型变量在内存中分配整型变量在内存中分配2 2个字节的存储单元。个字节的存储单元。n数值是以补码数值是以补码( (complement) complement) 表示的。表示的。 212.2.整型变量的分类整型变量的分类共六种共六种有符号基本整型有符号基本整型有符号短整型有符号短整型有符号长整型有符号长整型无符号基本整型无符号基本整型无

17、符号短整型无符号短整型无符号长整型无符号长整型(signed)int (signed)short (int )(signed) long (int)unsigned intunsigned short (int)unsigned long (int) 注意:注意:括号表示其中的内容是可选的括号表示其中的内容是可选的。2.3整型数据整型数据222.3整型数据整型数据 C C语言没有具体规定以上各类数据所占内存的字语言没有具体规定以上各类数据所占内存的字节数,只要求节数,只要求longlong型数据长度不短于型数据长度不短于intint型,型,shortshort型型不长于不长于intint型。具

18、体如何实现,由各计算机系统自行型。具体如何实现,由各计算机系统自行决定。如在决定。如在Turbo C+3.0Turbo C+3.0中,中,intint型和型和shortshort型数据都型数据都是是1616位位( (bit)bit),而而longlong型数据是型数据是3232位。位。 以整数以整数13 13 在在Turbo C+3.0Turbo C+3.0环境下,在各种整数环境下,在各种整数类型的存储单元中的存储情况如图所示。类型的存储单元中的存储情况如图所示。233. 3. 整型变量的定义整型变量的定义 规定在程序中所有用到的变量都必须在程序中定义,规定在程序中所有用到的变量都必须在程序中

19、定义, 变量说明的一般形式为:变量说明的一般形式为: 数据类型名数据类型名 变量名表;变量名表;(变量名之间用逗号分隔)(变量名之间用逗号分隔) 例如例如: : int a,b,c;int a,b,c;(指定变量、为整型)指定变量、为整型) unsigned short c,d;unsigned short c,d;(指定变量、为无符号短整型)指定变量、为无符号短整型) long e,f;long e,f;( (指定变量、为长整型)指定变量、为长整型)2.3整型数据整型数据24例例2.2整型变量的定义与使用。整型变量的定义与使用。# include void main() int a,b,c,

20、d; unsigned u; a=15; b=19; u=17; c=a+u; d=b+u; printf(“ c = a+u =%d, d=b+u=%dn”,c,d); 说明说明说明说明 可以看到不同种类的整型数据可以进行算术运算可以看到不同种类的整型数据可以进行算术运算程序运行结果为:程序运行结果为:c=a+u=32,d = b+u=22.3整型数据整型数据25例例2.3整型数据的溢出(见图)。整型数据的溢出(见图)。#include void main() int a,b; a=32767; b=a+1; printf(n a =%d , a+1= %d n,a,b); a=-32768

21、; b=a-1; printf(n a =%d, a-1=%d n,a,b); 说明:说明:说明:说明:数值是以补码表示的。一个整型变量只能容纳数值是以补码表示的。一个整型变量只能容纳- -32768327683276732767范围内的数,无法表示大于范围内的数,无法表示大于3276732767或小或小于于-32768-32768的数。遇此情况就发生的数。遇此情况就发生“溢出溢出”。程序运行结果为:程序运行结果为:a =32767, a+1=32768a =32768, a1 =327672.3整型数据整型数据4 4整型数据的溢出整型数据的溢出262.3.3整型常量的类型整型常量的类型 (1

22、) (1)一个整数,如果其值在一个整数,如果其值在-32768-32768+32767+32767范围内,认为它是范围内,认为它是intint型,它可以赋值给型,它可以赋值给intint型和型和long intlong int型变量。型变量。 (2) (2) 一个整数,如果其值超过了上述范围,而在一个整数,如果其值超过了上述范围,而在-2147483637-2147483637+2147483647+2147483647范围内,则认为它是为长整型。可以将它赋范围内,则认为它是为长整型。可以将它赋值给一个值给一个long intlong int型变量。型变量。 整型数据整型数据27(3) (3)

23、 如果所用的如果所用的C C版本分配给版本分配给short intshort int与与intint型数据在内存型数据在内存中占据的长度相同,则它的表数范围与中占据的长度相同,则它的表数范围与intint型相同。型相同。 (4) (4) 一个整常量后面加一个字母一个整常量后面加一个字母u u或或U U,认为是认为是unsigned unsigned intint型,如果写成型,如果写成-12345-12345u u,则先将则先将-12345-12345转换成其补码转换成其补码5319153191,然后按无符号数存储。,然后按无符号数存储。(5) (5) 在一个整常量后面加一个字母在一个整常量后

24、面加一个字母l l或或L L,则认为是则认为是long long intint型常量。型常量。 例如:例如: 123 123l.432L.0Ll.432L.0L2.3整型数据整型数据282.4 2.4 实型数据实型数据2.4.1 2.4.1 实型常量的表示方法实型常量的表示方法两种表示形式两种表示形式小数小数指数指数0.1230.1233 3e-3e-3注意注意: :字母字母e(e(或或E)E)之前必须有数字,且之前必须有数字,且e e后面的后面的指数必须为整数:指数必须为整数:1 1e3e3、1.8e-31.8e-3、-123e-6-123e-6、-.1e-3-.1e-3e3e3、2.1e3

25、.52.1e3.5、.e3.e3、e e 293.4浮点型数据浮点型数据规范化的指数形式:规范化的指数形式: 在字母在字母e e(或或E E)之前的小数部分中,小数点左边应只之前的小数部分中,小数点左边应只有一位非零的数字。有一位非零的数字。在在C C程序中,一个浮点数在用指数形程序中,一个浮点数在用指数形式输出时,是按规范化的指数形式输出的。式输出时,是按规范化的指数形式输出的。 例如例如: : 123.456123.456可以表示为:可以表示为: 123.456 123.456e0, 12.3456e1, 1.23456e2, 0.123456e3, e0, 12.3456e1, 1.23

26、456e2, 0.123456e3, 0.0123456e4, 0.00123456e0.0123456e4, 0.00123456e 其中的其中的1.234561.23456e3e3称为称为“规范化的指数形式规范化的指数形式”。30 2.4.2 2.4.2实实型变量型变量 1.1.实型数据在内存中的存放形式实型数据在内存中的存放形式 一个浮点型数据一般在内存中占一个浮点型数据一般在内存中占4 4个字节个字节(32(32位位) )。与整。与整型数据的存储方式不同,浮点型数据是按照指数形式存储的。型数据的存储方式不同,浮点型数据是按照指数形式存储的。系统把一个浮点型数据分成小数部分和指数部分,分

27、别存放。系统把一个浮点型数据分成小数部分和指数部分,分别存放。指数部分采用规范化的指数形式。指数部分采用规范化的指数形式。2.4 2.4 实型数据实型数据312 2实型变量的分类和定义实型变量的分类和定义 实实型变量分为单精度(型变量分为单精度(floatfloat型)、双精度(型)、双精度(doubledouble型)和长双精度型(型)和长双精度型(long doublelong double)三类形式。三类形式。表表2.2 2.2 实型数据的分类实型数据的分类例如:例如:float x1 float x1 ,x2x2; ( (指定指定x1x1、x2x2为单精度浮点数为单精度浮点数) )do

28、uble y1 double y1 ; ( (指定指定y1y1为双精度浮点数为双精度浮点数) )long double z1 long double z1 ; ( (指定指定z1z1为长双精度浮点数为长双精度浮点数) ) 2.4 2.4 实型数据实型数据32例例2.4 2.4 实型数据的舍入误差。实型数据的舍入误差。# # include include void main()void main() float x1float x1,x2x2;x1x1333333.222E5333333.222E5x2x2x1+30x1+30;printf (x1 = printf (x1 = f nf n,

29、x1)x1);printf (x2 = printf (x2 = f nf n,x2)x2); 说明:说明:说明:说明:一个浮点型变量只能保证的有效数字是一个浮点型变量只能保证的有效数字是7 7位有效数字,位有效数字,后面的数字是无意义的,并不准确地表示该数。后面的数字是无意义的,并不准确地表示该数。 应当避免将一个很大的数和一个很小的数直接相加应当避免将一个很大的数和一个很小的数直接相加或相减,否则就会或相减,否则就会“丢失丢失”小的数。小的数。与此类似,用计算与此类似,用计算机计算机计算1.03.03.0的结果不可能等于的结果不可能等于1.0。程序运行结果为:程序运行结果为:x1=3333

30、3321728.000000x2=33333321728.0000002.4 2.4 实型数据实型数据3 3实型数据的舍入误差实型数据的舍入误差 332.4.3 2.4.3 实型常量的类型实型常量的类型 C C编译系统将浮点型常量作为双精度来处理。编译系统将浮点型常量作为双精度来处理。 例如例如:f = 2.45678 * 4523.65f = 2.45678 * 4523.65 系统先把系统先把2.456782.45678和和4523.654523.65作为双精度数,然后进行作为双精度数,然后进行相乘的运算,得到的乘也是一个双精度数。最后取其前相乘的运算,得到的乘也是一个双精度数。最后取其前

31、7 7位赋给浮点型变量位赋给浮点型变量f f。如是在数的后面加字母如是在数的后面加字母f f或或F F(如如1.651.65f, 654.87Ff, 654.87F),),这样编译系统就会把它们按单精度这样编译系统就会把它们按单精度(3232位)处理。位)处理。假如:假如: float yfloat y; y y1234567.11111234567.1111; float float型变量型变量y y只能接收只能接收7 7位有效数字位有效数字2.4 2.4 实型数据实型数据342.5 2.5 字符型数据字符型数据 2.5.1 2.5.1 字符常量字符常量(1 1)字字符符常常量量只只能能用用

32、单单引引号号括括起起来来,不不能能用用双双引引号号或或其其他他括号。括号。(2 2)字符常量只能是单个字符。)字符常量只能是单个字符。(3 3)字符可以是字符集中任意字符。)字符可以是字符集中任意字符。 (4 4)C C语言还允许用一种特殊形式的字符常量,就是以一语言还允许用一种特殊形式的字符常量,就是以一个字符个字符“ ”开头的字符序列,称之为开头的字符序列,称之为“转义字符转义字符”。 表表2.3转义字符及其含义转义字符及其含义35 有些以有些以“ ”开头的特殊字符称为转义字符开头的特殊字符称为转义字符 n n 换行换行 t t 横横向跳格向跳格 r r 回回车车 反反斜杠斜杠 ddddd

33、d ddd ddd表示表示1 1到到3 3位八进制数字位八进制数字 xhhxhh hh hh表示表示1 1到到2 2位十六进制数字位十六进制数字2.5 2.5 字符型数据字符型数据 36例例2.5转义字符的使用。转义字符的使用。#include void main()int a,b,c;a=5; b=6; c=7;printf(%dnt%d %dn %d %dtb%dn,a,b,c,a,b,c); n程序运行时输出以下结果:程序运行时输出以下结果:2.5 2.5 字符型数据字符型数据 372.5.2字符型变量字符型变量1. 1. 字符型变量分类和定义字符型变量分类和定义n字字符符型型变变量量用

34、用来来存存放放字字符符常常量量,注注意意只只能能放放一一个个字字符符。一个字符变量在内存中占一个字节。一个字符变量在内存中占一个字节。n字符变量的定义形式如下:字符变量的定义形式如下:char c1,c2;char c1,c2;n在本函数中可以用下面语句对在本函数中可以用下面语句对c1,c2c1,c2赋值:赋值: c1c1a a;c2c2 b b ;2.5 2.5 字符型数据字符型数据 382.2.字符型数据在内存中的存储形式及其使用方法字符型数据在内存中的存储形式及其使用方法 字符型数据在内存中的存储是将字符的字符型数据在内存中的存储是将字符的ASCIIASCII码值以二进码值以二进制形式存

35、放,占用制形式存放,占用1 1个字节。也就是说将一个字符型常量放个字节。也就是说将一个字符型常量放到一个字符变量中,实际上并不是把该字符本身放到内存单到一个字符变量中,实际上并不是把该字符本身放到内存单元中去,而是将该字符的相应的元中去,而是将该字符的相应的ASCIIASCII代码放到存储单元中。代码放到存储单元中。 这样使字符型数据和整型数据之间可以通用。一个字符这样使字符型数据和整型数据之间可以通用。一个字符数据既可以以字符形式输出,也可以以整数形式输出。数据既可以以字符形式输出,也可以以整数形式输出。2.5 2.5 字符型数据字符型数据 39例例2.6向字符型变量赋值。向字符型变量赋值。

36、# include void main() /* 字符字符a的各种表达方法的各种表达方法 */ char c1,c2,c3,c4,c5,c6;c1=a; c2=x61; c3=141; c4=97; c5=0x61; c6=0141; printf(c1=%c,c2=%c,c3=%cn,c1,c2,c3);printf(c4=%c,c5=%c,c6=%cn, c4,c5,c6); printf(c1=%d,c2=%d,c3=%dn,c1,c2,c3); printf(c4=%d,c5=%d,c6=%dn,c4,c5,c6);程序运行结果:程序运行结果:c1=a,c2=a,c3=ac4=a,c5

37、=a,c6=ac1=97,c2=97,c3=97c4=97,c5=97,c6=972.5 2.5 字符型数据字符型数据 40例例2.7字符型数据的转换。字符型数据的转换。# include void main() char c1,c2,c3; c1=a; c2=b; c1=c1-32; c2=c2-32; c3=157; printf(n c1=%c c2=%c c3=%cn,c1,c2,c3); printf(c1=%d c2=%d c3=%dn,c1,c2,c3); 程序运行结果:程序运行结果:c1=Ac2=Bc3= c1=65c2=66c3=99 2.5 2.5 字符型数据字符型数据41

38、注意:注意:注意:注意: 需要进一步说明的是有些系统需要进一步说明的是有些系统( (如如Turbo C+3.0 ) )将字符将字符变量定义为变量定义为signed char型。其存储单元中的最高位作为符号位,型。其存储单元中的最高位作为符号位,它的取值范围就是它的取值范围就是128127。 如果在字符变量中存放一个如果在字符变量中存放一个ASCII码为码为0127间的字符,间的字符,由于字节中最高位为由于字节中最高位为0,因此用,因此用d输出字符变量时,输出的是输出字符变量时,输出的是一个正整数。一个正整数。 如果在字符变量中存放一个如果在字符变量中存放一个ASCII码为码为128255间的字

39、间的字符,由于在字节中最高位为符,由于在字节中最高位为1,用,用d格式符输出时,就会得到格式符输出时,就会得到一个负整数,一个负整数, 2.5 2.5 字符型数据字符型数据 422.5.3字符串常量字符串常量C语语言言除除了了允允许许使使用用字字符符常常量量外外,还还允允许许使使用用字字符符串串常常量量。字符串常量是一对双引号括起来的字符序列。字符串常量是一对双引号括起来的字符序列。例如:例如: ”This is a C program”, ”CHINA”, ”a”, ”a1f3.45”也可以利用也可以利用printf函数可以输出一个字符串。函数可以输出一个字符串。例如:例如:printf(A

40、llaloneinaforeignland.);2.5 2.5 字符型数据字符型数据 43设设ch1ch1被指定为字符变量:被指定为字符变量: char ch1; char ch1; ch1= ch1=a a; ; 是正确的。是正确的。 是字符常量是字符常量而而 ch1=ch1=”a a”;则是错误的。则是错误的。 ”是字符串常量是字符串常量规规定定:在在每每一一个个字字符符串串常常量量的的结结尾尾加加一一个个 “字字符符串串结结束束标标志志”,以以便便系系统统据据此此判判断断字字符符串串是是否否结结束束。规规定定以以字字符符作为字符串结束标志。作为字符串结束标志。2.5 2.5 字符型数据字

41、符型数据 注意:注意:在写字符串时不必加在写字符串时不必加00,因为,因为00字符是系统字符是系统自动加上的。在自动加上的。在C C语言中没有专门的字符串变量,如果想将一语言中没有专门的字符串变量,如果想将一个字符串存放在变量中以便保存,必须使用字符数组,即用个字符串存放在变量中以便保存,必须使用字符数组,即用一个字符型数组来存放一个字符串。一个字符型数组来存放一个字符串。44 2.6 变量初始化和变量赋初值变量初始化和变量赋初值(1)(1)语言允许在定义变量的同时使变量初始化。语言允许在定义变量的同时使变量初始化。如如: : int a=3;int a=3; / / 指定为整型变量,初值为指

42、定为整型变量,初值为 float f=3.56;float f=3.56; / / 指定为浮点型变量,初值为指定为浮点型变量,初值为.56 .56 char c= char c= a a; ; / / 指定为字符变量,初值为指定为字符变量,初值为a a(2)(2)可以使被定义的变量的一部分赋初值。可以使被定义的变量的一部分赋初值。 如如: : int a,b,c=5int a,b,c=5; 表示指定、为整型变量,但表示指定、为整型变量,但只对初始化,只对初始化,c c的初值为的初值为 45 变量初始化和变量赋初值变量初始化和变量赋初值(3)(3)如果对几个变量赋以同一个初值,如果对几个变量赋以

43、同一个初值, 应写成:应写成:int a=3,b=3,c=3; int a=3,b=3,c=3; 表示、的初值都表示、的初值都是。是。 不能写成不能写成 int a=b=c=3;int a=b=c=3; 注意:注意:初始化不是在编译阶段完成的,而是在程序运行初始化不是在编译阶段完成的,而是在程序运行时执行本函数时赋初值的,相当于有一个赋值语句。时执行本函数时赋初值的,相当于有一个赋值语句。46例例分析下列程序的输出。#include int a, b = 1;int main()int c = 2, d;printf(“a=%d,b=%d,c=%d,d=%dn”,a,b,c,d);return

44、 0;【运行结果】:a=0,b=1,c=2,d=-85899346047【例例2-12】数值溢出:#include int main()short x = 32767,sum;unsigned short ux = -1;sum = x + 1;printf( “ sum = %d,ux = %dn”, sum, ux); return 0;【运行结果】:sum = -32768,ux = 655352.4运算符与表达式运算符与表达式49运算符运算符n运算符运算符是表示对数据(对象)进行某种操作的符号,又称操作符,被操作的对象称操作数操作数。C语言中根据操作数的个数把运算符分为:一元运算符,只

45、需要一个操作数,例如:+(正号),-(负号),+(自加),-(自减)等;二元运算符,需要两个操作数,例如:+(加号),-(减号),*(乘),/(除)等等;以及三元运算符,需要三个操作数,只有一个?:,即条件运算符。字面量。50表达式表达式n表达式表达式是由操作数和运算符组成的序列,它可以表示一个值或一个对象或一个函数调用或对某些对象进行修改的动作。最简单的表达式就是一个常量或一个标识符或一个字符串字面量。51【例例2-14】表达式表达式nfloat pi = 3.14f, r = 2.8f;nchar str = “I am an expression.”;n2 * pi * rn这里的pi、

46、3.14f、r、2.8f、“I am an expression”和pi = 3.14f、r = 2.8f、str = “I am an expression.”、 2 * pi * r都是表达式。522.4.1赋值语句赋值语句n赋值运算的一般形式是:n变量名变量名=表达式;表达式;n【说明】:n赋值运算是二元运算符,其作用是把右边表达式的值赋给(拷贝)左边的变量(表达式),因此其左操作数必须是一个能返回非const型的变量。例如上面的a、b、c。n赋值运算还要求右操作数的类型与左操作数的类型兼容,即右边表达式的类型能够自动转换为左表达式的数据类型。53算术算术运算符和运算符和算术算术表达式表

47、达式2.7.1 C语言语言运算符简介运算符简介 的运算符有以下几类:的运算符有以下几类:(1)(1)算术运算符算术运算符 (+ - * / %+ - * / %)(2)(2)关系运算符关系运算符 (!)(!)(3)(3)逻辑运算符逻辑运算符 (!(!|)(4)(4)位运算符位运算符(二进制位的运算)(二进制位的运算) ( (右(右移移) 取反取反| |或或异异或或与与)(5)(5)赋值运算符赋值运算符 (及其扩展赋值运算符)(及其扩展赋值运算符)(6)(6)条件运算符条件运算符 (?:)(?:)(7)(7)逗号运算符逗号运算符 ( (,),)54(8)(8)指针运算符指针运算符 (* *和)和

48、)(9)(9)求字节数运算符()求字节数运算符()(10)(10)强制类型转换运算符(强制类型转换运算符( ( (类型)类型) ) )(11)(11)分量运算符(分量运算符(-)(12)(12)下标运算符()下标运算符()(13)(13)其他其他 (如函数调用运算符()(如函数调用运算符()2.7 算术算术运算符和运算符和算术算术表达式表达式552.7.2 2.7.2 基本算术运算符和算术表达式基本算术运算符和算术表达式1 1基本的算术运算符基本的算术运算符 (加法运算符,或正值运算符,如(加法运算符,或正值运算符,如: :、)、) (减法运算符,或负值运算符,如(减法运算符,或负值运算符,如

49、: :、)、) * * (乘法运算符,如(乘法运算符,如: :* *) (除法运算符,包括整数除和实数除,如(除法运算符,包括整数除和实数除,如25253 3、4.24.22.0) 2.0) (模运算符,或称求余运算符,两侧均应为整型(模运算符,或称求余运算符,两侧均应为整型数据,如数据,如: :的值为)。的值为)。2.7 算术算术运算符和运算符和算术算术表达式表达式562. 2. 算术表达式和运算符的优先级与结合性算术表达式和运算符的优先级与结合性 用算术运算符和括号将运算对象用算术运算符和括号将运算对象( (也称操作数)连接起来也称操作数)连接起来的、符合语法规则的式子,称为算术表达式。运

50、算对象包的、符合语法规则的式子,称为算术表达式。运算对象包括常量、变量、函数等。括常量、变量、函数等。 例如例如: : * *.5.5aa 是一个合法的表达式。是一个合法的表达式。2.7 算术算术运算符和运算符和算术算术表达式表达式57n语言规定了运算符的优先级和结合性。语言规定了运算符的优先级和结合性。 在表达式求值时,先按运算符的优先级别高低次序执在表达式求值时,先按运算符的优先级别高低次序执行,例如先乘除后加减。行,例如先乘除后加减。 n规定了各种运算符的结合方向规定了各种运算符的结合方向( (结合性结合性) ) 算术运算符的结合方向为算术运算符的结合方向为“自左至右自左至右”,即先左后

51、右,即先左后右 。 注注意意:C C语语言言规规定定了了各各种种运运算算符符的的结结合合方方向向( (结结合合性性) ), “自自左左至至右右的的结结合合方方向向又又称称“左左结结合合性性”,即即运运算算对对象象先先与与左左面面的的运运算算符符结结合合。有有些些运运算算符符的的结结合合方方向向为为“自自右至左右至左” ( (例如,赋值运算符例如,赋值运算符) )。 在程序运行时,系统会自动进行结合性的运算的。在程序运行时,系统会自动进行结合性的运算的。2.7 算术算术运算符和运算符和算术算术表达式表达式582.7.32.7.3自增、自减运算符自增、自减运算符 自自增增运运算算符符记记为为“+”

52、,其其功功能能是是使使变变量量的的值值自自增增1 1。自自减减1 1运算符记为运算符记为“”,其功能是使变量值自减,其功能是使变量值自减1 1。如如: ,(在使用之前,先使的值加(减)(在使用之前,先使的值加(减) ,(在使用之后,使的值加(减)(在使用之后,使的值加(减) 2.7 算术算术运算符和运算符和算术算术表达式表达式说明:说明:一般来说,一般来说,+i i和和i+i+的作用相当于的作用相当于i ii+1i+1。但但+i i和和i+i+不同之处在于不同之处在于+i i是先执行是先执行i ii+1i+1后,再使用后,再使用i i的值;而的值;而i+i+是先使用是先使用i i的值后,再执行

53、的值后,再执行i ii+1i+1。-i-i和和i-i-的作用相当的作用相当于于i ii-1i-1。但但-i i和和i-i-不同之处在于不同之处在于-i i是先执行是先执行i ii-1i-1后,后,再使用再使用i i的值;而的值;而i-i-是先使用是先使用i i的值后,再执行的值后,再执行i ii-1i-1。 59i+i+与与+i i的区别:的区别: 是先执行后,再使用的值;是先执行后,再使用的值; 是先使用的值后,再执行。是先使用的值后,再执行。例如:例如: ; i i的值先变成的值先变成4, 4, 再赋给再赋给, ,j j的值均为的值均为 ; 先将先将 i i的值的值3 3赋给赋给, ,的值

54、为,然后变为的值为,然后变为2.7 算术算术运算符和运算符和算术算术表达式表达式60注意:注意: (1) (1)自增运算符(),自减运算符(),只能用于自增运算符(),自减运算符(),只能用于变量,而不能用于常量或表达式,变量,而不能用于常量或表达式, (2) (2)和的结合方向是和的结合方向是“自右至左自右至左”。如:如:9+9+或或( (a+b)+a+b)+都是不合法的。都是不合法的。 因因为为9 9是是常常量量,常常量量的的值值不不能能改改变变,不不可可能能出出现现“9=9+19=9+1”的形式。的形式。 ( (a+b)+a+b)+也也不不可可能能实实现现,因因为为自自增增、自自减减运运

55、算算还还有有一一种种给给变量赋值的功能。变量赋值的功能。2.7 算术算术运算符和运算符和算术算术表达式表达式61例例2.8 2.8 变量自增、自减运算举例。变量自增、自减运算举例。 # # include include void main()void main() int i=7; /*i int i=7; /*i的初值为的初值为7*/7*/printf(%d ,+i); /* iprintf(%d ,+i); /* i加加1 1后输出故为后输出故为8*/8*/printf(%d ,-i); /* iprintf(%d ,-i); /* i减减1 1后输出故为后输出故为7*/7*/print

56、f(%d ,i+); /*printf(%d ,i+); /*输出输出i i为为7 7之后再加之后再加1(1(为为8)*/8)*/printf(%d ,i-); /*printf(%d ,i-); /*输出输出i i为为8 8之后再减之后再减1(1(为为7)*/7)*/printf(%d ,-i+); /*printf(%d ,-i+); /*输出输出-7-7之后之后i i再加再加1(1(为为8)*/8)*/printf(%dn,-i-); printf(%dn,-i-); /* /*输出输出-8-8之后之后i i再减再减1(1(为为7)*/7)*/ 2.7 算术算术运算符和运算符和算术算术表

57、达式表达式程序运行结果:程序运行结果:8778-7-862例例2.9较复杂的变量自增、自减运算举例。较复杂的变量自增、自减运算举例。# include void main() int i=3,j=6,p,q;p=(i+)+(i+)+(i+);q=(+j)+(+j)+(+j);printf(p=%d q=%d i=%d j=%dn,p,q,i,j);2.7 算术算术运算符和运算符和算术算术表达式表达式程序运行结果:程序运行结果:632.7.4 2.7.4 有关算术表达式使用中的问题说明有关算术表达式使用中的问题说明(1) (1) ANSI CANSI C并没有具体规定表达式的求值顺序,允许各编译

58、并没有具体规定表达式的求值顺序,允许各编译系统自己安排。系统自己安排。 例如例如:对表达式对表达式 a = f1( )+f2( )a = f1( )+f2( ) 并不是所有的编译系统都先调用并不是所有的编译系统都先调用f1( )f1( ), 然后然后调用调用f2( )f2( )。在有的情况下结果可能不同。有时会出在有的情况下结果可能不同。有时会出现一些令人容易搞混的问题,因此务必要小心谨慎。现一些令人容易搞混的问题,因此务必要小心谨慎。例例2.10 2.10 自增自减运算的求值顺序。自增自减运算的求值顺序。 2.7 算术算术运算符和运算符和算术算术表达式表达式64(2 2)C C编译系统在处理

59、程序时尽可能多地编译系统在处理程序时尽可能多地( (自左而右自左而右) )将将若干个字符组成一个运算符、标识符和关键字。若干个字符组成一个运算符、标识符和关键字。 语言中有的运算符为一个字符,有的运算符由两语言中有的运算符为一个字符,有的运算符由两个字符组成个字符组成 ,为避免误解,最好采取大家都能理解的,为避免误解,最好采取大家都能理解的写法。写法。 例如例如:不要写成不要写成i+ji+j的形式,的形式, 而应写成而应写成( (i+)+ji+)+j的形式的形式 2.7 算术算术运算符和运算符和算术算术表达式表达式65(3 3)在调用函数时,实参数的求值顺序,标准并无统一规)在调用函数时,实参

60、数的求值顺序,标准并无统一规定。定。 例如:例如:的初值为,如果有下面的函数调用:的初值为,如果有下面的函数调用: printfprintf(,i+)i+) 在有的系统中,从左至右求值,输出在有的系统中,从左至右求值,输出“,”。在多。在多数系统中对函数参数的求值顺序是自右而左,输出的是数系统中对函数参数的求值顺序是自右而左,输出的是“,”。以上这种写法不宜提倡,最好改写成。以上这种写法不宜提倡,最好改写成 j = i+; printf(%dj = i+; printf(%d, %d %d, j j,i)i) 不要写出别人看不懂的也不知道系统会怎样执行程序不要写出别人看不懂的也不知道系统会怎样

61、执行程序2.7 算术算术运算符和运算符和算术算术表达式表达式662.4.3关系运算关系运算n关系运算的结果本应为布尔值(真或假),C99以前没有布尔类型,而是用0和非零来表示逻辑假和真。如果关系运算的结果为真,则用1表示,为假则用0表示,故关系关系运算的结果为整型值。n=、=虽然由两个符号构成,但它们各代表一个运算符,中间不能有空格。n注意赋值运算符(=)与相等运算符(=)的区别,由于的缘故,如果不小心把=错写成了=,编译器将无法识别。67【例例2-20】int main()int r1 = ( 3 = 5 );printf( r1 = %dnr2 = %dn, r1, r2);【运行结果】:

62、r1 = 1 r2 = 068关系表达式关系表达式n由关系运算符连接的表达式就是关系表由关系运算符连接的表达式就是关系表达式,关系表达式的类型为整型达式,关系表达式的类型为整型692.4.4逻辑运算逻辑运算n逻辑非:!逻辑非:!n语法:!语法:!op;op是数值量或结果可以自动转化为数值量是数值量或结果可以自动转化为数值量的表达式。的表达式。n结果:若结果:若op为为0,则结果为,则结果为1;否则,即;否则,即op非非0,则结果,则结果为为0。n逻辑与:逻辑与:&n语法:语法:op1&op2;op1、op2数值量或结果可以自数值量或结果可以自动转化为数值量的表达式。动转化为数值量的表达式。n结

63、果:若结果:若op1和和op2皆非皆非0,则结果为,则结果为1,否则,结果为,否则,结果为0。n逻辑或:逻辑或:|n语法:语法:op1|op2;op1、op2数值量或结果可以自动数值量或结果可以自动转化为数值量的表达式。转化为数值量的表达式。n结果:若结果:若op1和和op2皆为皆为0,则结果为,则结果为0,否则,结果为,否则,结果为1。70【例例2-21】逻辑运算int main()int i = 100;float f = 0.1f;int r = !i;printf( r = %dn, r);r = i & f;printf( r = %dn, r);r = i | f;printf(

64、r = %dn, r);return 0;【运行结果运行结果】:r=0r=1r=171逻辑表达式逻辑表达式n用逻辑运算符连接起来的数值量或结果可以自动转化为数值量的表达式称为逻辑表达式。逻辑表达式的运算结果只能是0或1,所以逻辑表达式的类型可以看着是整型。722.4.5位运算位运算n位运算是对操作数按二进制位作某种操作的运算符,C语言有左移()、按位取非()、按位或(|)、按位异或()和按位与(&)六个73移位移位 P.32nop nn移位运算得到是移位后的数值(右值),而不是变量,所以移位运算的操作数可以是常量或变量。n移位运算不改变原操作数的值。nn是大于等于0且小于op位数的整数。n右移

65、时,将保持符号位不变,最低位移出;左移时低位补,最高位移出。74【例例2-23】移位运算int main()const char c = -97;int i = -1;char c1 = c 2;char c2 = c 2;int i1 = i 3;printf( c = %dti = %dn, c, i );printf( c1 = %dtc2 = %dti1 = %dn, c1, c2, i1 );return 0;【运行结果】:c = -97 i = -1c1 = -25 c2 = 124 i1 = -875按位非按位非nopn运算把op的所有位(包括符号位)取反,返回取反后的值,原变量

66、保持不变。nop是整型变量或常量或返回整型变量或常量的表达式。76【例例2-24】按位非运算。int _tmain()const char c = -97;signed char c1 = c;printf( c = %dtc1 = %dn, c, c1 );return 0;【运行结果】:c = -97 c1 = 9677按位与、或及异或运算按位与、或及异或运算n一般形式:op1 & 或 | 或 op2nop1和op2是整型变量或常量。n如果op1和op2的长度不同,则会对较短的操作数进行整提升。n返回op1和op2按位(含符号位)与、或、异或运算后的整数,不影响原操作数的值。78【例例2-

67、25】int main()const char c1 = -97, c2 = 68;char c = c1 & c2;printf( c1=%dtc2=%dtc1&c2=%dn, c1,c2,c);short s, s1 = -97, s2 = 68;s = s1 | s2;printf( s1=%dts2=%dts1|s2=%dn, s1,s2,s);s = c1 | s2;printf( c1=%dts2=%dtc1|s2=%dn, c1,s2,s);return 0;【运行结果运行结果】:c1=-97 c2=68 c1&c2=4s1=-97 s2=68 s1|s2=-33c1=97 s2

68、=68 c1|s2=-33792.4.6复合表达式复合表达式nC语言规定算术运算符和位运算符都可以和赋值运算符组合成符合赋值运算符,即:n+= -= *= /= %= = &= = |=n复合赋值运算是赋值运算的变种,其左操作数必须是可写的变量或返回可写变量左值的表达式。80【例例2-26】复合赋值运算int main()int i = 0;i += 5;printf( i=%dn, i);i = 5;printf( i=%dn, i);i |= 5;printf( i=%dn, i);i *= 5;printf( i=%dn, i);return 0;【运行结果运行结果】:i=5i=0i=5

69、i=25812.4.7类型转换类型转换n使用强制转换运算符可以把表达式的结果硬性转换为一个用户指定的类型。其一般形式为:n(类型)表达式(类型)表达式82【例例2-27】int main()int n=5;double d1,d2;d1 = n / 2 ;d2 = (double)n / 2 ;n = (int)d2 ;printf( d1 = %f, d2 = %f, n = %dn , d1, d2, n) ;return 0 ;【运行结果】:d1 = 2.000000 d2 = 2.500000 n = 283说明说明n强制类型转换可以实现高类型到低类型的转换,也可以实现低类型到高类型的

70、转换,但是高类型到低类型转换是可能引起精度损失。n浮点类型到整型的转换必须强制执行,只转换浮点数的整数部分,而不是四舍五入。例如:double d = 1.83219E4 ; int i = (int)d ;则i=18321,而不是18322。84自动类型转换自动类型转换n在算术运算、赋值运算等双操作数运算中,参与运算的操作数的类型可以不同,但是在运算时需要把他们转换为同一类型,然后再运算。85自动类型转换自动类型转换n实际是把表示范围小/精度低的数据类型转换为表示范围大/精度高的数据类型,因此又称类型提升。在算术运算中,类型提升会自动进行。n在赋值运算中,如果把表示范围小的类型的数据赋值给表

71、示范围大的类型的变量,转换过程也会自动进行,但如果相反,就必须进行强制类型转换。862.8 各种数值类型数据间的转换和运算各种数值类型数据间的转换和运算(P.32)(P.32) 2.8.1 2.8.1 隐式转换隐式转换 整型(包括整型(包括int,short,longint,short,long)、)、浮点型(包括浮点型(包括float,doublefloat,double)可以混合运算。在进行运算时,不同类型的可以混合运算。在进行运算时,不同类型的数据要先转换成同一类型数据要先转换成同一类型, ,然后进行运算。然后进行运算。转换的目的是:转换的目的是:(1 1)将短的数扩展成机器处理的长度。

72、)将短的数扩展成机器处理的长度。(2 2)使得运算符两侧的数据类型相同。)使得运算符两侧的数据类型相同。例如:下面式子在例如:下面式子在C C语言中是能够通过类型转换进行计算的。语言中是能够通过类型转换进行计算的。 63+ 63+a a-16*8+15.95-16*8+15.95该类型转换是由系统自动进行的,该类型转换是由系统自动进行的,转换的规则转换的规则 :如图:如图87(3)(3)强制类型转换运算符强制类型转换运算符 可以利用强制类型转换运算符将一个表达式转换成可以利用强制类型转换运算符将一个表达式转换成所需类型。所需类型。 一般形式一般形式: :(类型名)(表达式)(类型名)(表达式)

73、例如:例如:n( (double)double) 将转换成将转换成doubledouble类型类型n( (int)(x+y) int)(x+y) 将将x+yx+y的值转换成整型的值转换成整型n( (float)float)(5%35%3) 将将5%35%3的值转换成的值转换成floatfloat型型2.8 各种数值类型数据间的转换和运算各种数值类型数据间的转换和运算882.8 各种数值类型数据间的转换和运算各种数值类型数据间的转换和运算 说说明明:需需要要转转换换的的表表达达式式应应该该用用括括号号括括起起来来。在在强强制制类类型型转转换换时时,得得到到一一个个所所需需类类型型的的中中间间变变

74、量量,原原来来变变量量的类型未发生变化。的类型未发生变化。 float x=3.6;float x=3.6; int a; int a; a=(int)x; a=(int)x;注意:注意:强制类型转换实际上是一种单目运算。各种数强制类型转换实际上是一种单目运算。各种数据类型名都可以用来作强制类型换的运算符,如据类型名都可以用来作强制类型换的运算符,如(char)、()、(int)、()、(float)等。等。 892.9 赋值运算符和赋值表达式赋值运算符和赋值表达式1. 1. 赋值运算符和赋值表达式赋值运算符和赋值表达式 赋赋值值符符号号“”就就是是赋赋值值运运算算符符,它它的的作作用用是是将

75、将一一个个数数据据赋给一个变量。也可以将一个表达式的值赋给一个变量。赋给一个变量。也可以将一个表达式的值赋给一个变量。 赋值运算符按照赋值运算符按照“自右而左自右而左”的结合顺序的结合顺序 赋赋值值表表达达式式是是赋赋值值运运算算符符将将一一个个变变量量和和一一个个表表达达式式连连接接起起来的式子。它的一般形式为:来的式子。它的一般形式为: 下面是赋值表达式的例子:下面是赋值表达式的例子: k=b k=bc c7 k=5+(c7 k=5+(c6) 6) k=(b k=(b5)+(c=4) k=(b5)+(c=4) k=(b8)%(c=3)8)%(c=3)90 2 2类型转换类型转换 如果赋值运

76、算符两侧的类型不一致,但都是数值型或字符如果赋值运算符两侧的类型不一致,但都是数值型或字符型时,在赋值时要进行类型转换。型时,在赋值时要进行类型转换。 (1 1)将将实实型型数数据据(单单、双双精精度度)赋赋给给整整型型变变量量,舍舍弃弃实实数数的小数部分,以整数形式存储到变量中。的小数部分,以整数形式存储到变量中。 如如: :为整型变量,执行为整型变量,执行“i=3.56i=3.56”的结果是使的结果是使 的值为,以整数形式存储在整型变量中。的值为,以整数形式存储在整型变量中。 (2 2)将将doubledouble型型数数据据赋赋给给floatfloat型型变变量量时时,截截取取其其前前面

77、面7 7位位有有效效数数字字,存存放放到到floatfloat变变量量的的存存储储单单元元中中(32(32bits)bits)。但但同同样样应注意数值范围不能溢出。应注意数值范围不能溢出。 2.9 赋值运算符和赋值表达式赋值运算符和赋值表达式91 (4 4)将一个)将一个intint、shortshort、longlong型数据赋给一个型数据赋给一个charchar型变量型变量时,只将其低时,只将其低8 8位原封不动地送到位原封不动地送到charchar型变量型变量( (即高位截去即高位截去) )。若将一个若将一个longlong型数据赋给一个型数据赋给一个intint型变量,只将型变量,只将

78、longlong型数据中型数据中低低1616位原封不动地送到整型变量位原封不动地送到整型变量( (即高位截去即高位截去) )。 例如:例如:long a=32769;long a=32769;int b;int b;b=a;b=a;2.9 赋值运算符和赋值表达式赋值运算符和赋值表达式说明:说明:不同类型的整型数据间的赋值归根到底就是不同类型的整型数据间的赋值归根到底就是一条:按存储单元中的存储形式直接传送。一条:按存储单元中的存储形式直接传送。 923 3复合的赋值运算符和赋值表达式复合的赋值运算符和赋值表达式在在赋赋值值运运算算符符“= =”之之前前加加上上其其他他二二目目运运算算符符可可构

79、构成成复复合合赋赋值值符。符。 即:即:+=+=、 -= -=、 *= *=、= =、%=%=、=、&=&=、=、|=|=例如:例如:a+=5 a+=5 等价于等价于 a=a+5a=a+5x*=y+7 x*=y+7 等价于等价于 x=x*(y+7)x=x*(y+7)r%=p r%=p 等价于等价于 r=r%p r=r%p 2.9 赋值运算符和赋值表达式赋值运算符和赋值表达式93讨论讨论1:赋值表达式也可以包含复合的赋值运算符。赋值表达式也可以包含复合的赋值运算符。 如:如:a+=a-=a*aa+=a-=a*a分析分析: :此赋值表达式的求解步骤如下此赋值表达式的求解步骤如下 先进行先进行“*

80、*”的运算,的运算, 它相当于它相当于* *,a a的值为的值为144144132132。 再进行再进行“”的运算,相当于的运算,相当于= =a+(-a+(-132)132),a a的值为的值为132-132132-132-264-264。讨论讨论2 2:赋值表达式也可以包含复合的赋值运算符。例如:若赋值表达式也可以包含复合的赋值运算符。例如:若a a为为3 3,求下列表达式的值:,求下列表达式的值: a+a+a-a-a*=aa*=a2.9 赋值运算符和赋值表达式赋值运算符和赋值表达式94讨论讨论3 3: 将赋值表达式作为表达式的一种,使赋值操作将赋值表达式作为表达式的一种,使赋值操作不仅可以

81、出现在赋值语句中,而且可以以表达式形式出不仅可以出现在赋值语句中,而且可以以表达式形式出现在其他语句(如输出语句、循环语句等)中。现在其他语句(如输出语句、循环语句等)中。 如:如:printf(%dprintf(%d,a=b);a=b); 分析分析: : 如果如果b b的值为的值为3 3, 则输出则输出a a的值的值( (也是表达式也是表达式a=ba=b的的值值) )为为3 3。在一个语句中完成了赋值和输出双重功能。在一个语句中完成了赋值和输出双重功能。2.9 赋值运算符和赋值表达式赋值运算符和赋值表达式95sizeofn由于C语言没有规定整型变量的长度,因而不同的实现同一类型的某些变量占用

82、的字节数可能是不同的,于是要想获知某类型变量的实际字节数,最好的办法是用sizeof运算符。其一般使用形式是:nsizeof(表达式)(表达式)n其中,表达式可以是变量名、常量以及类型名96【例例2-28】求输出结果int main()int i=2; int j=sizeof(+i);printf(i = %dnj = %dn, i, j ); return 0;【运行结果】:i = 2j = 4972.4.8?n问号表达式是C语言中唯一的一个三操作数运算,一般使用形式如下:na?b:cn其中a、b、c是三个表达式,如果表达式a的值为逻辑真(即非0),则计算并返回表达式b的值;如果表达式a的

83、值为逻辑假(即等于0),则计算并返回表达式c的值98【例例2-29】求输出结果int main()int a = 0, b = 1;int c = a b ? a+ :b;printf( “a = %dnb = %dnc = %dn”, a,b,c ); return 0;【运行结果运行结果】:a = 0b = 1c = 1992.11 逗号运算符和逗号表达式逗号运算符和逗号表达式 在在C C语语言言中中“,”也也是是一一种种特特殊殊的的运运算算符符逗逗号号运运算算符符,又又称称为为“顺顺序序求求值值运运算算符符”。用用逗逗号号运运算算符符将将若若干干个个表表达达式式连接起来的式子称为逗号表达

84、式。连接起来的式子称为逗号表达式。例如:例如:3+5, 3+5, a=14, b=4, a+b, r=a+b-2a=14, b=4, a+b, r=a+b-2逗号表达式的一般形式可以扩展为:逗号表达式的一般形式可以扩展为:表达式表达式1 1,表达式,表达式2 2,表达式,表达式3 3,表达式,表达式n n 逗逗号号表表达达式式的的求求解解过过程程是是:先先求求解解表表达达式式1 1,再再求求解解表表达达式式2 2,依依次次求求到到表表达达式式n n,表表达达式式n n的的值值就就是是整整个个逗逗号号表表达达式式的的值。值。的值为的值为4,b的值为的值为4.12,然后求,然后求解解+b,得得18

85、。整个逗号表达整个逗号表达式的值为式的值为16。100 优先级优先级: : 逗号运算符是所有运算符中级别最低的逗号运算符是所有运算符中级别最低的赋值运算赋值运算符的优先级别高于逗号运算符,逗号运算符是所有运算符中符的优先级别高于逗号运算符,逗号运算符是所有运算符中级别最低的。级别最低的。 例如,下面两个表达式的,作用是不同的:例如,下面两个表达式的,作用是不同的: x x(a(a5 5,7* 3) 7* 3) x xa a8 8,6* 2 6* 2 前一个是一个赋值表达式,将一个逗号表达式的值赋给前一个是一个赋值表达式,将一个逗号表达式的值赋给x x,x x的值等于的值等于2121,同时变量,

86、同时变量a a的值为的值为5 5。后一个是逗号表达式,。后一个是逗号表达式,包括一个赋值表达式和一个算术表达式,包括一个赋值表达式和一个算术表达式,x x的值为的值为8 8,整个逗,整个逗号表达式的值为号表达式的值为1212,变量,变量a a的值为的值为8 8。 2.11 逗号运算符和逗号表达式逗号运算符和逗号表达式101注意注意: :并不是任何地方出现的逗号都是作为逗号运算符。例如并不是任何地方出现的逗号都是作为逗号运算符。例如函数参数也是用逗号来间隔的。函数参数也是用逗号来间隔的。如如:printf(“%d,%d,%d”,a,b,c);printf(“%d,%d,%d”,(a,b,c),b

87、,c)“(,(,)”是一个是一个逗号表达式,逗号表达式,它的值等于它的值等于的值。的值。 2.11 逗号运算符和逗号表达式逗号运算符和逗号表达式102【例例2-30】分析下列程序的输出结果。分析下列程序的输出结果。intmain(void)inta=0,b1,b2,b3,b4;b1=(a+,a+,a+);printf(b1=%dta=%dn,b1,a);a=0;b2=(+a,+a,+a);printf(b2=%dta=%dn,b2,a);a=0;b3=a+,a+,a+;printf(b3=%dta=%dn,b3,a);a=0;b4=+a,+a,+a;printf(b4=%dta=%dn,b4,

88、a);scanf(%*c);return0;【运行结果运行结果】:b1 = 2a = 3b2 = 3a = 3b3 = 0a = 3b4 = 1a = 31032.4.8,n同时声明多个变量或函数的参数时也使用逗号作为变量间的分隔符,但不应把这些逗号也当做逗号运算符来理解,只需把它们当做分隔符就可以了,否则会导致理解困难。n逗号运算符的优先级最低,且其结合方向是左结合。例如,上例中的b3和b4实际上是在逗号运算之前完成的赋值,故其值分别是0和1。n注意逗号运算符与短路运算符(2.4.4)的区别。逗号运算要按从左到右的顺序依次计算每一个表达式,而短路运算在某些情况下将忽略第二个操作数。1042.

89、4.9优先级优先级&结合性结合性 当一个表达式中有多个运算符时,如何决定这些运算符的执行次序呢?这就涉及运算符的优先级与结合性。同数学计算一样,运算符具有不同的优先级,在同一表达式中,优先级高的运算先执行,然后次之。同一优先级的运算符由运算符的结合性来决定其执行顺序。在所有的运算符中,括号的优先级最高,如果有括号,就必须优先执行括号中的运算。105错误的赋值错误的赋值int main()float f1, f2 = 2.0 f;int i1 = 2; int i2;f1 = i1; /正确,f1=1.0i2 = f2; /编译错误,float类型不能自动转换为int类型。return 0;10

90、6【例例2-17】int main()int a = 5, b = 2,s;s = a / b;printf( s = %d n, s);a = -5, b = 2;s = a / b;printf( s = %d n, s);a = 5, b = -2;s = a / b;printf( s = %d n, s);a = -5, b = -2;s = a / b;printf( s = %d n, s); return 0; 【运算结果运算结果】:s = 2s = -2s = -2s = 2107【例例2-17】intmain()floata=5.0f,b=2.0f,s;s=a/b;prin

91、tf(s=%fn,s);a=-5.0,b=2.0;s=a/b;printf(s=%fn,s);a=5.0f,b=-2.0f;s=a/b;printf(s=%fn,s);a=-5.0f,b=-2.0f;s=a/b;printf(s=%fn,s);return0;【运行结果运行结果】:s = 2.500000s = -2.500000s = -2.500000s = 2.500000108【例例2-17】intmain()shorta=5,b=2,s;s=a%b;/s=1printf(s=%dn,s);a=-5,b=2;s=a%b;/s=-1printf(s=%dn,s);a=5,b=-2;s=a

92、%b;/s=1printf(s=%dn,s);a=-5,b=-2;s=a%b;/s=-1printf(s=%dn,s);return0;【运行结果运行结果】:s = 1s = -1s = 1s = -1109int main()int a = 10;printf( a = %dn, a);int b = -a;int c = a-;int m = -a+;printf( b = %d, c = %dn,b,c);printf( a = %d, m = %dn,a, m);return 0;【运行结果运行结果】:a = 10b = 9, c = 9a = 9, m = -8110【例例2-19】分析下列程序的输出:int main()int a =1;printf(%d %d %dn, a, a+, a+);a =1;printf(%d %d %dn, a, +a, +a);return 0;【运行结果运行结果】:3 2 13 3 3

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 医学/心理学 > 基础医学

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号