《第02章数据类型、运算符和表达式.ppt》由会员分享,可在线阅读,更多相关《第02章数据类型、运算符和表达式.ppt(110页珍藏版)》请在三一文库上搜索。
1、,第二章,数据类型、运算符与表达式,C的数据类型 常量与变量 算术运算符和算术表达式 各种数值类型数据间的转换和运算 赋值运算符和赋值表达式 位运算,本章教学要点,2.1 C的数据类型 2.2 常量与变量 2.3 整型数据 2.4 实型数据 2.5 字符型数据,主要内容,2.6 变量初始化和变量赋初值 2.7 算术运算符和算术表达式 2.8 各种数值类型数据间的转换和运算 2.9 赋值运算符和赋值表达式 2.10 位运算 2.11 逗号运算符和逗号表达式,主要内容,2.1 C的数据类型,C语言提供了以下一些数据类型。给变量定义数据类型,实际上是为数据在内存中分配规定的存储空间,存储空间通常用字
2、节数的形式表示。,数据类型,构造类型,指针类型,空类型 void,2.2 常量与变量,3.2.1 常量和符号常量 在程序运行过程中,其值不能被改变的量称为常量。常量区分为不同的类型:例如,整型 100,125,-100,0 实型 3.14 , 0.125,-3.789 字符型 a, b,2 字符串 a, ab,1232,符号常量: 用一个标识符代表一个常量。符号常量的值在其作用域内不能改变,也不能再被赋值。,例2.1定义一个符号常量PI,表示圆周率。然后使用符号常量PI计算圆的周长。 # include # define PI 3.14 /*定义符号常量PI,表示3.14*/ void mai
3、n() float r,l; r=5.0; l = 2*r*PI; printf(“l=%fn”,l ); ,程序运行结果为: l = 31.400000,说明: 程序中用#define命令行定义PI代表常量3.14,此后凡在本文件中出现的PI都代表3.14,可以和常量一样进行运算,说明:如再用赋值语句给PI赋值是错的 如: PI=40;/* 错误,不能给符号常量赋值,2.2 常量与变量,常量,常量就是一个确知的量。程序设计语言中还可以狭义地理解为编译时能够确定,运行时不能修改的量。C语言是强类型语言,任何对象都必须有明确的类型,常量也不例外。C语言中的常量分整型常量、浮点型常量、字符常量和枚
4、举常量四类。,整形常量,3.3.1 整型常量的表示方法 整型常量即整常数。在语言中,整常数可用以下三种形式表示: (1)十进制整数。 如:123, -456.4,3.1415926。 (2)八进制整数。以0头的数是八进制数。 如:0123表示八进制数123,等于十进制数83, -011表示八进制数-11,即十进制数-9。 (3)十六进制整数。以0x开头的数是16进制数。 如:0x123,代表16进制数123,等于十进制数 291。 -0x12等于十进制数18。,浮点型常量,C89规定,浮点常量只能使用十进制。 浮点数的书写可以直接书写或采用指数形式。采用指数形式时以10底数,用e/E表示指数。
5、 指数部分必须为整数,不能是小数,不能带小数点。 指数部分的+可以省略,默认为正,。 浮点常量的默认类型是double型,但是,和整型常量一样也可以通过添加后缀来改变浮点常量的类型: f/F:表示该浮点常量为float型。 l/L:表示该浮点常量为long double型。,字符型常量,字符常量就是用单引号 括起来的一个字符或一个转义字符序列。例如:a、A、?、$、a、n等等。 转义字符序列以反斜杠打头,其后跟一个字母或13位的八进制数或x(不是0x)加12位的十六进制数,用来表示某种特殊的含义,如代表另外一个字符或某个动作等。,字符串常量,字符串常量就是用双引号括起来的字符序列,又称为字符串
6、字面量,常简称为字符串。 凡是用双引号括起来的,不管里面有多少个字符,都称为字符串。 字符串以0作为结束标志,字符串中间不能含有该字符。例如,上例中的”a”,在内存中实际存放的是97(a的ASCII码)和0。再如下例将得不到预期的结果。,字符串常量,凡是用双引号括起来的,不管里面有多少个字符,都称为字符串。 字符串以0作为结束标志,字符串中间不能含有该字符。例如,上例中的”a”,在内存中实际存放的是97(a的ASCII码)和0。再如下例将得不到预期的结果。,变量,就象算术运算中我们可以定义一个符号来代表一个未知数一样,C语言中也可以定义一个合法的标志符来代表一个数据,称为变量。该标识符实际对应
7、一块内存区域,数据就存放在该内存区域中,CPU可以读取该内存区域中的数据(即读),也可以在该内存区域上存入新的数据(即写)。命名变量的标志符必须满足标识符命名规则。,变量,2.2.2 变量 变量代表内存中具有特定属性的一个存储单元,它用来存放数据,这就是变量的值,在程序运行期间,这些值是可以改变的。 变量名实际上是一个以一个名字对应代表一个地址,在对程序编译连接时由编译系统给每一个变量名分配对应的内存地址。从变量中取值,实际上是通过变量名找到相应的内存地址,从该存储单元中读取数据。,2.2 常量与变量,变量名必须是标识符 例:sum,_total, month, Stu_name, l_1_2
8、,BC235 M.D.John, ¥123,3D64, ab,注意: 编译系统将大写字母和小写字母认为是两个不同的字符。 在C语言中,要求对所有用到的变量作强制定义,也就是“先定义,后使用”,凡未被事先定义的,C编译系统不把它认作变量名,这就能保证程序中变量名使用得正确。 在选择变量名和其它标识符时,应注意做到“见名知意”,即选有含意的英文单词 (或其缩写)作标识符。 每一个变量被指定为一个确定类型,在编译时就能为其分配相应的存储单元。,例,【例2-7】变量的定义及赋值。 int x = 10; int main() int y; y = x; return 0; 上例中定义了一个全局变量x和
9、一个局部变量y,x的初始值为10,主函数中把x的值赋给y。,声明,类型修饰存储类类型 变量列表 【例2-8】声明变量 int age, hight, weight; / 三个int型变量。 unsigned short int age; / age为unsigned short int类型。 const volatile char in_buffer; / 字符变量 static float tmp; / 静态的float型变量。,2.3.2 整型变量 1. 整型数据在内存中的存放形式 数据在内存中是以二进制形式存放的。 如: int i; /* 定义为整型变量 */ i=17; /* 给i赋
10、以整数17 */,2.3 整型数据,注意: 十进制数17的二进制形式为10001,Turbo C+ 3.0为一个整型变量在内存中分配2个字节的存储单元。 数值是以补码(complement) 表示的。,2.整型变量的分类,共六种,有符号基本整型 有符号短整型 有符号长整型 无符号基本整型 无符号短整型 无符号长整型,(signed)int (signed)short (int ) (signed) long (int) unsigned int unsigned short (int) unsigned long (int),注意:括号表示其中的内容是可选的。,2.3 整型数据,2.3 整型数
11、据,C语言没有具体规定以上各类数据所占内存的字节数,只要求long型数据长度不短于int型,short型不长于int型。具体如何实现,由各计算机系统自行决定。如在Turbo C+3.0中,int型和short型数据都是16位(bit),而long型数据是32位。 以整数13 在Turbo C+3.0环境下,在各种整数类型的存储单元中的存储情况如图所示。,3. 整型变量的定义 规定在程序中所有用到的变量都必须在程序中定义, 变量说明的一般形式为: 数据类型名 变量名表;(变量名之间用逗号分隔) 例如: int a,b,c;(指定变量、为整型) unsigned short c,d;(指定变量、为
12、无符号短整型) long e,f;(指定变量、为长整型),2.3 整型数据,例2.2 整型变量的定义与使用。 # include void main() int a,b,c,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=2,2.3 整型数据,例2.3 整型数据的溢出(见图)。 #include void main() int a,b; a=32767; b=a+1;
13、printf(“n a =%d , a+1= %d n“,a,b); a=-32768; b=a-1; printf(“n a =%d, a-1=%d n“,a,b); ,说明:数值是以补码表示的。一个整型变量只能容纳-3276832767范围内的数,无法表示大于32767或小于-32768的数。遇此情况就发生“溢出”。,程序运行结果为: a =32767, a+1=32768 a =32768, a1 =32767,2.3 整型数据,4整型数据的溢出,2.3.3 整型常量的类型 (1)一个整数,如果其值在-32768+32767范围内,认为它是int型,它可以赋值给int型和long int
14、型变量。 (2) 一个整数,如果其值超过了上述范围,而在-2147483637+2147483647范围内,则认为它是为长整型。可以将它赋值给一个long int型变量。,整型数据,(3) 如果所用的C版本分配给short int与int型数据在内存中占据的长度相同,则它的表数范围与int型相同。 (4) 一个整常量后面加一个字母u或U,认为是unsigned int型,如果写成-12345u,则先将-12345转换成其补码53191,然后按无符号数存储。 (5) 在一个整常量后面加一个字母l或L,则认为是long int型常量。 例如: 123l.432L.0L,2.3 整型数据,2.4 实
15、型数据,2.4.1 实型常量的表示方法,两种表示形式,小数 指数,0.123 3e-3,注意:字母e(或E)之前必须有数字,且e后面的指数必须为整数:,1e3、1.8e-3、-123e-6、-.1e-3 e3、2.1e3.5、.e3、e,3.4 浮点型数据,规范化的指数形式: 在字母e(或E)之前的小数部分中,小数点左边应只有一位非零的数字。在C程序中,一个浮点数在用指数形式输出时,是按规范化的指数形式输出的。 例如: 123.456可以表示为: 123.456e0, 12.3456e1, 1.23456e2, 0.123456e3, 0.0123456e4, 0.00123456e 其中的1
16、.23456e3称为“规范化的指数形式”。,2.4.2实型变量 1.实型数据在内存中的存放形式 一个浮点型数据一般在内存中占4个字节(32位)。与整型数据的存储方式不同,浮点型数据是按照指数形式存储的。系统把一个浮点型数据分成小数部分和指数部分,分别存放。指数部分采用规范化的指数形式。,2.4 实型数据,2实型变量的分类和定义 实型变量分为单精度(float型)、双精度(double型)和长双精度型(long double)三类形式。 表2.2 实型数据的分类 例如: float x1 ,x2; (指定x1、x2为单精度浮点数) double y1 ; (指定y1为双精度浮点数) long d
17、ouble z1 ; (指定z1为长双精度浮点数),2.4 实型数据,例2.4 实型数据的舍入误差。 # include void main() float x1,x2; x1333333.222E5 x2x1+30; printf (“x1 = f n“,x1); printf (“x2 = f n“,x2); ,说明:一个浮点型变量只能保证的有效数字是7位有效数字,后面的数字是无意义的,并不准确地表示该数。 应当避免将一个很大的数和一个很小的数直接相加或相减,否则就会“丢失”小的数。与此类似,用计算机计算1.03.03.0的结果不可能等于1.0。,程序运行结果为: x1 =33333321
18、728.000000 x2 =33333321728.000000,2.4 实型数据,3实型数据的舍入误差,2.4.3 实型常量的类型 C编译系统将浮点型常量作为双精度来处理。 例如:f = 2.45678 * 4523.65 系统先把2.45678和4523.65作为双精度数,然后进行相乘的运算,得到的乘也是一个双精度数。最后取其前7位赋给浮点型变量f。如是在数的后面加字母f或F(如1.65f, 654.87F),这样编译系统就会把它们按单精度(32位)处理。 假如: float y; y1234567.1111; float型变量y只能接收7位有效数字,2.4 实型数据,2.5 字符型数据
19、,2.5.1 字符常量 (1)字符常量只能用单引号括起来,不能用双引号或其他括号。 (2)字符常量只能是单个字符。 (3)字符可以是字符集中任意字符。 (4)C语言还允许用一种特殊形式的字符常量,就是以一个字符“”开头的字符序列,称之为“转义字符”。 表2.3 转义字符及其含义,有些以“”开头的特殊字符称为转义字符,n 换行 t 横向跳格 r 回车 反斜杠 ddd ddd表示1到3位八进制数字 xhh hh表示1到2位十六进制数字,2.5 字符型数据,例2.5 转义字符的使用。 #include void main() int a,b,c; a=5; b=6; c=7; printf(“%dn
20、t%d %dn %d %dtb%dn“,a,b,c,a,b,c); ,程序运行时输出以下结果:,2.5 字符型数据,2.5.2 字符型变量 1. 字符型变量分类和定义 字符型变量用来存放字符常量,注意只能放一个字符。一个字符变量在内存中占一个字节。 字符变量的定义形式如下:char c1,c2; 在本函数中可以用下面语句对c1,c2赋值: c1a;c2 b ;,2.5 字符型数据,2.字符型数据在内存中的存储形式及其使用方法 字符型数据在内存中的存储是将字符的ASCII码值以二进制形式存放,占用1个字节。也就是说将一个字符型常量放到一个字符变量中,实际上并不是把该字符本身放到内存单元中去,而是
21、将该字符的相应的ASCII代码放到存储单元中。,这样使字符型数据和整型数据之间可以通用。一个字符数据既可以以字符形式输出,也可以以整数形式输出。,2.5 字符型数据,例2.6 向字符型变量赋值。 # 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
22、,c2=%d,c3=%dn“,c1,c2,c3); printf(“c4=%d,c5=%d,c6=%dn“,c4,c5,c6); ,程序运行结果: c1=a,c2=a,c3=a c4=a,c5=a,c6=a c1=97,c2=97,c3=97 c4=97,c5=97,c6=97,2.5 字符型数据,例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=
23、%d c3=%dn“,c1,c2,c3); ,程序运行结果: c1=A c2=B c3= c1=65 c2=66 c3=99,2.5 字符型数据,注意: 需要进一步说明的是有些系统(如Turbo C+3.0 )将字符变量定义为signed char型。其存储单元中的最高位作为符号位,它的取值范围就是128127。 如果在字符变量中存放一个ASCII码为0127间的字符,由于字节中最高位为0,因此用d输出字符变量时,输出的是一个正整数。 如果在字符变量中存放一个ASCII码为128255间的字符,由于在字节中最高位为1,用d格式符输出时,就会得到一个负整数,,2.5 字符型数据,2.5.3 字符
24、串常量 C语言除了允许使用字符常量外,还允许使用字符串常量。字符串常量是一对双引号括起来的字符序列。 例如: ”This is a C program”, ”CHINA”, ”a”, ”a1f3.45” 也可以利用printf函数可以输出一个字符串。 例如: printf(“All alone in a foreign land.“);,2.5 字符型数据,设ch1被指定为字符变量: char ch1; ch1=a; 是正确的。 是字符常量 而 ch1=”a”;则是错误的。 ”是字符串常量 规定:在每一个字符串常量的结尾加一个 “字符串结束标志”,以便系统据此判断字符串是否结束。规定以字符作为
25、字符串结束标志。,2.5 字符型数据,注意:在写字符串时不必加0,因为0字符是系统自动加上的。在C语言中没有专门的字符串变量,如果想将一个字符串存放在变量中以便保存,必须使用字符数组,即用一个字符型数组来存放一个字符串。,2.6 变量初始化和变量赋初值,(1)语言允许在定义变量的同时使变量初始化。 如: int a=3; / 指定为整型变量,初值为 float f=3.56; / 指定为浮点型变量,初值为.56 char c= a; / 指定为字符变量,初值为a (2)可以使被定义的变量的一部分赋初值。 如: int a,b,c=5; 表示指定、为整型变量,但只对初始化,c的初值为,变量初始化
26、和变量赋初值,(3)如果对几个变量赋以同一个初值, 应写成:int a=3,b=3,c=3; 表示、的初值都是。 不能写成 int a=b=c=3;,注意:初始化不是在编译阶段完成的,而是在程序运行时执行本函数时赋初值的,相当于有一个赋值语句。,例,分析下列程序的输出。 #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 0; 【运行结果】: a=0,b=1,c=2,d=-858993460,【例2-12】,数值溢出: #include int main()
27、 short x = 32767,sum; unsigned short ux = -1; sum = x + 1; printf( “ sum = %d,ux = %dn”, sum, ux); return 0; 【运行结果】: sum = -32768,ux = 65535,2.4 运算符与表达式,运算符,运算符是表示对数据(对象)进行某种操作的符号,又称操作符,被操作的对象称操作数。C语言中根据操作数的个数把运算符分为:一元运算符,只需要一个操作数,例如:+(正号),-(负号),+(自加),-(自减)等;二元运算符,需要两个操作数,例如:+(加号),-(减号),*(乘),/(除)等等;
28、以及三元运算符,需要三个操作数,只有一个?:,即条件运算符。字面量。,表达式,表达式是由操作数和运算符组成的序列,它可以表示一个值或一个对象或一个函数调用或对某些对象进行修改的动作。最简单的表达式就是一个常量或一个标识符或一个字符串字面量。,【例2-14】表达式,float pi = 3.14f, r = 2.8f; char str = “I am an expression.”; 2 * pi * r 这里的pi、3.14f、r、2.8f、“I am an expression”和pi = 3.14f、r = 2.8f、str = “I am an expression.”、 2 * pi
29、 * r都是表达式。,2.4.1 赋值语句,赋值运算的一般形式是: 变量名 = 表达式; 【说明】: 赋值运算是二元运算符,其作用是把右边表达式的值赋给(拷贝)左边的变量(表达式),因此其左操作数必须是一个能返回非const型的变量。例如上面的a、b、c。 赋值运算还要求右操作数的类型与左操作数的类型兼容,即右边表达式的类型能够自动转换为左表达式的数据类型。,算术运算符和算术表达式,2.7.1 C语言运算符简介 的运算符有以下几类: (1)算术运算符 (+ - * / %) (2)关系运算符 (!) (3)逻辑运算符 (!|) (4)位运算符(二进制位的运算) (右移) 取反|或异或与) (5
30、)赋值运算符 (及其扩展赋值运算符) (6)条件运算符 (?:) (7)逗号运算符 (,),(8)指针运算符 (*和) (9)求字节数运算符() (10)强制类型转换运算符( (类型) ) (11)分量运算符(-) (12)下标运算符( ) (13)其他 (如函数调用运算符(),2.7 算术运算符和算术表达式,2.7.2 基本算术运算符和算术表达式 1基本的算术运算符 (加法运算符,或正值运算符,如:、) (减法运算符,或负值运算符,如:、) * (乘法运算符,如:*) (除法运算符,包括整数除和实数除,如253、4.22.0) (模运算符,或称求余运算符,两侧均应为整型数据,如:的值为)。,
31、2.7 算术运算符和算术表达式,2. 算术表达式和运算符的优先级与结合性 用算术运算符和括号将运算对象(也称操作数)连接起来的、符合语法规则的式子,称为算术表达式。运算对象包括常量、变量、函数等。 例如: *.5a 是一个合法的表达式。,2.7 算术运算符和算术表达式,语言规定了运算符的优先级和结合性。 在表达式求值时,先按运算符的优先级别高低次序执行,例如先乘除后加减。 规定了各种运算符的结合方向(结合性) 算术运算符的结合方向为“自左至右”,即先左后右 。 注意:C语言规定了各种运算符的结合方向(结合性), “自左至右的结合方向又称“左结合性”,即运算对象先与左面的运算符结合。有些运算符的
32、结合方向为“自右至左” (例如,赋值运算符)。 在程序运行时,系统会自动进行结合性的运算的。,2.7 算术运算符和算术表达式,2.7.3自增、自减运算符 自增运算符记为“+”,其功能是使变量的值自增1。自减1运算符记为“”,其功能是使变量值自减1。 如: ,(在使用之前,先使的值加(减) ,(在使用之后,使的值加(减),2.7 算术运算符和算术表达式,说明:一般来说,+i和i+的作用相当于ii+1。但+i和i+不同之处在于+i是先执行ii+1后,再使用i的值;而i+是先使用i的值后,再执行ii+1。-i和i-的作用相当于ii-1。但-i和i-不同之处在于-i是先执行ii-1后,再使用i的值;而
33、i-是先使用i的值后,再执行ii-1。,i+与+i的区别: 是先执行后,再使用的值; 是先使用的值后,再执行。 例如: ; i的值先变成4, 再赋给,j的值均为 ; 先将 i的值3赋给,的值为,然后变为,2.7 算术运算符和算术表达式,注意: (1)自增运算符(),自减运算符(),只能用于变量,而不能用于常量或表达式, (2)和的结合方向是“自右至左”。 如:9+或(a+b)+都是不合法的。 因为9是常量,常量的值不能改变,不可能出现“9=9+1”的形式。 (a+b)+也不可能实现,因为自增、自减运算还有一种给变量赋值的功能。,2.7 算术运算符和算术表达式,例2.8 变量自增、自减运算举例。
34、 # include void main() int i=7; /*i的初值为7*/ printf(“%d “,+i); /* i加1后输出故为8*/ printf(“%d “,-i); /* i减1后输出故为7*/ printf(“%d “,i+); /*输出i为7之后再加1(为8)*/ printf(“%d “,i-); /*输出i为8之后再减1(为7)*/ printf(“%d “,-i+); /*输出-7之后i再加1(为8)*/ printf(“%dn“,-i-); /*输出-8之后i再减1(为7)*/,2.7 算术运算符和算术表达式,程序运行结果: 8 7 7 8 -7 -8,例2.
35、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 算术运算符和算术表达式,程序运行结果:,2.7.4 有关算术表达式使用中的问题说明 (1) ANSI C并没有具体规定表达式的求值顺序,允许各编译系统自己安排。 例如:对表达式 a = f1( )+f2( ) 并不是所有的编译系统都先调用f1( ), 然后 调用f2( )。在有的情况下结果可能不同。有时会出 现一些令人容
36、易搞混的问题,因此务必要小心谨慎。 例2.10 自增自减运算的求值顺序。,2.7 算术运算符和算术表达式,(2)C编译系统在处理程序时尽可能多地(自左而右)将若干个字符组成一个运算符、标识符和关键字。 语言中有的运算符为一个字符,有的运算符由两个字符组成 ,为避免误解,最好采取大家都能理解的写法。 例如:不要写成i+j的形式, 而应写成(i+)+j的形式,2.7 算术运算符和算术表达式,(3)在调用函数时,实参数的求值顺序,标准并无统一规定。 例如:的初值为,如果有下面的函数调用: printf(,i+) 在有的系统中,从左至右求值,输出“,”。在多数系统中对函数参数的求值顺序是自右而左,输出
37、的是“,”。以上这种写法不宜提倡,最好改写成 j = i+; printf(“%d, %d“, j,i),不要写出别人看不懂的也不知道系统会怎样执行程序,2.7 算术运算符和算术表达式,2.4.3关系运算,关系运算的结果本应为布尔值(真或假),C99以前没有布尔类型,而是用0和非零来表示逻辑假和真。如果关系运算的结果为真,则用1表示,为假则用0表示,故关系关系运算的结果为整型值。 =、=虽然由两个符号构成,但它们各代表一个运算符,中间不能有空格。 注意赋值运算符(=)与相等运算符(=)的区别,由于的缘故,如果不小心把=错写成了=,编译器将无法识别。,【例2-20】,int main() int
38、 r1 = ( 3 = 5 ); printf( “r1 = %dnr2 = %dn“, r1, r2); 【运行结果】: r1 = 1 r2 = 0,关系表达式,由关系运算符连接的表达式就是关系表达式,关系表达式的类型为整型,2.4.4 逻辑运算,逻辑非:! 语法:!op;op是数值量或结果可以自动转化为数值量的表达式。 结果:若op为0,则结果为1;否则,即op非0,则结果为0。 逻辑与:& 语法:op1 & op2;op1、op2数值量或结果可以自动转化为数值量的表达式。 结果:若op1和op2皆非0,则结果为1,否则,结果为0。 逻辑或:| 语法:op1 | op2;op1、op2数值
39、量或结果可以自动转化为数值量的表达式。 结果:若op1和op2皆为0,则结果为0,否则,结果为1。,【例2-21】,逻辑运算 int main() int i = 100; float f = 0.1f; int r = !i; printf( “r = %dn“, r); r = i ,【运行结果】: r=0 r=1 r=1,逻辑表达式,用逻辑运算符连接起来的数值量或结果可以自动转化为数值量的表达式称为逻辑表达式。逻辑表达式的运算结果只能是0或1,所以逻辑表达式的类型可以看着是整型。,2.4.5 位运算,位运算是对操作数按二进制位作某种操作的运算符,C语言有左移()、按位取非()、按位或(|
40、)、按位异或()和按位与(&)六个,移位 P.32,op n 移位运算得到是移位后的数值(右值),而不是变量,所以移位运算的操作数可以是常量或变量。 移位运算不改变原操作数的值。 n是大于等于0且小于op位数的整数。 右移时,将保持符号位不变,最低位移出;左移时低位补,最高位移出。,【例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 = %d
41、ti1 = %dn“, c1, c2, i1 ); return 0; 【运行结果】: c = -97 i = -1 c1 = -25 c2 = 124 i1 = -8,按位非,op 运算把op的所有位(包括符号位)取反,返回取反后的值,原变量保持不变。 op是整型变量或常量或返回整型变量或常量的表达式。,【例2-24】,按位非运算。 int _tmain() const char c = -97; signed char c1 = c; printf( “c = %dtc1 = %dn“, c, c1 ); return 0; 【运行结果】: c = -97 c1 = 96,按位与、或及异或
42、运算,一般形式: op1 & 或 | 或 op2 op1和op2是整型变量或常量。 如果op1和op2的长度不同,则会对较短的操作数进行整提升。 返回op1和op2按位(含符号位)与、或、异或运算后的整数,不影响原操作数的值。,【例2-25】,int main() const char c1 = -97, c2 = 68; char c = c1 ,【运行结果】: c1=-97 c2=68 c1&c2=4 s1=-97 s2=68 s1|s2=-33 c1=97 s2=68 c1|s2=-33,2.4.6 复合表达式,C语言规定算术运算符和位运算符都可以和赋值运算符组合成符合赋值运算符,即:
43、+= -= *= /= %= = &= = |= 复合赋值运算是赋值运算的变种,其左操作数必须是可写的变量或返回可写变量左值的表达式。,【例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=5 i=0 i=5 i=25,2.4.7 类型转换,使用强制转换运算符可以把表达式的结果硬性转换为一个用户指定的类型。
44、其一般形式为: (类型)表达式,【例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 = 2,说明,强制类型转换可以实现高类型到低类型的转换,也可以实现低类型到高类型的转换,但是高类型到低类型转换是可能引起精度损失。 浮点类型到整型的转换必须强制执行,只转换浮点数的整数部分
45、,而不是四舍五入。例如:double d = 1.83219E4 ; int i = (int)d ;则i=18321,而不是18322。,自动类型转换,在算术运算、赋值运算等双操作数运算中,参与运算的操作数的类型可以不同,但是在运算时需要把他们转换为同一类型,然后再运算。,自动类型转换,实际是把表示范围小/精度低的数据类型转换为表示范围大/精度高的数据类型,因此又称类型提升。在算术运算中,类型提升会自动进行。 在赋值运算中,如果把表示范围小的类型的数据赋值给表示范围大的类型的变量,转换过程也会自动进行,但如果相反,就必须进行强制类型转换。,2.8 各种数值类型数据间的转换和运算(P.32),
46、2.8.1 隐式转换 整型(包括int,short,long)、浮点型(包括float,double)可以混合运算。在进行运算时,不同类型的数据要先转换成同一类型,然后进行运算。转换的目的是: (1)将短的数扩展成机器处理的长度。 (2)使得运算符两侧的数据类型相同。 例如:下面式子在C语言中是能够通过类型转换进行计算的。 63+a-16*8+15.95,该类型转换是由系统自动进行的, 转换的规则 :如图,(3)强制类型转换运算符 可以利用强制类型转换运算符将一个表达式转换成 所需类型。 一般形式:(类型名)(表达式) 例如: (double) 将转换成double类型 (int)(x+y)
47、将x+y的值转换成整型 (float)(5%3) 将5%3的值转换成float型,2.8 各种数值类型数据间的转换和运算,2.8 各种数值类型数据间的转换和运算,说明:需要转换的表达式应该用括号括起来。在强制类型转换时,得到一个所需类型的中间变量,原来变量的类型未发生变化。 float x=3.6; int a; a=(int)x;,注意:强制类型转换实际上是一种单目运算。各种数据类型名都可以用来作强制类型换的运算符,如(char)、(int)、(float)等。,2.9 赋值运算符和赋值表达式,1. 赋值运算符和赋值表达式 赋值符号“”就是赋值运算符,它的作用是将一个数据赋给一个变量。也可以将一个表达式的值赋给一个变量。 赋值运算符按照“自右而左”的结合顺序 赋值表达式是赋值运算符将一个变量和一个表达式连接起来的式子。它的一般形式为: 下面是赋值表达式的例子: k=bc7 k=5+(c6) k=(b5)+(c=4) k=(b8)%(c=3),2类型转换 如果赋值运算符两侧的类型不一致,但都是数值型或字符型时,在赋值时要进行类型转换。 (1)将实型数据(单、双精度)赋给整型变量,舍弃实数的小数部分,以整数形式存储到变量中。 如:为整型变量,执行“i=3.56”的结果是使 的值为,以整数形式存储在整型变
链接地址:https://www.31doc.com/p-2250337.html