1、第2讲,第3章:数据类型、运算符与表达式,2019/5/30,2,要点,C的几种基本数据类型 常量与变量的概念 整型、实型、字符型数据 变量赋初值 各类数值数据之间的混合运算基本运算符和表达式,2019/5/30,3,一、C的数据类型,程序 = 数据结构 + 算法 C语言中,数据结构以数据类型的形式出现int a,b,sum; /* 定义变量 */float x,y; 所谓数据类型是按被说明量的性质,表示形式,占据存储空间的多少,构造特点来划分的。,2019/5/30,4,在语言中,数据类型可分为:,2019/5/30,5,二、常量与变量,常量:在程序执行过程中,其值不发生改变的量如12,-3
2、,8.0,1.2e-3,a,M等。错误:12=5,12=n 不能被赋值 符号常量: C允许用一个标识符代表一个常量。即符号常量,一般使用大写英文字母表示。#define 标识符 常量如:# define PRICE 30 定义之后,系统就认为PRICE它的值为30;,按数据取值是否可改变分为常量和变量,2019/5/30,6,#define PRICE 30 main() int num,total;num=10;total=num*PRICE;printf(“total=%d“,total); 输出 total=300,若程序中PRICE改变为35 , #define PRICE 35 提高
3、程序的可读性及常量修改的一致性,PRICE=20;,2019/5/30,7,变量,3,p,变量名,变量值,变量:在程序执行过程中,取值可变的量,可以多次被赋值。如 int p; p=3;p=p+1;,2019/5/30,8,变量名(命名规则-标识符) 变量的类型(整型、实型、字符型等) 变量要先定义后使用定义时,系统给变量分配内存,变量名是一 个符号地址;系统根据变量的类型,分配不等的 内存空间。如:int-2个字节,float - 4个字节 变量的值 变量中存放的数据是变量的值,a,x,2,3.5,2019/5/30,9,标识符有如下规定: 1)c中的标识符是由字母、数字、下划线组成,且第一
4、个字符不能是数字。如:sum、 _size、data_38;错误:3D64、$123、M.D.JOHN。 注意:sum不同于SUM(区分大小写),一般变量名用小写字母。 2)不同C版本对标识符的长度要求不同,Turbo C允许32个字符,建议变量名的长度不要超过8个字符。 3)C语言中有32个关键字和12个预处理命令,不允许用户再次定义。 4)尽量做到见名知义,增加程序的可读性。如: name day total,表示数值的 a b x1 y2 i j,2019/5/30,10,对变量的值的操作 赋值:变量相当于一个容器,可以存储数据。float m; /*实型的变量*/ 先定义m=3.2;
5、/*实型的数据*/ 赋值 取值:从变量中取值,实际上是通过变量名找到相应的内存单元,从中读取变量的值。n=m*2; /*第1次取值*/ 后使用p=m+3; /*第2次取值*/多次取值,值不变。,2019/5/30,11,与数据类型结合起来分类。可分为:整型常量、整型变量,实型常量、实型变量,字符常量、字符变量字符串常量,2019/5/30,12,整型常量(整常数),1、C语言中,有三种表示形式: 十进制(数码取值:09) 如:0,123, - 81。 八进制(以开头,数码取值:07) 如:0123 (十进制的83), 011(十进制为 9),0177777(十进制为65535)。 十六进制(以
6、0x或0X开头,数码取值:0F或0f)。 如:0x2a(十进制为42),0XA0 (十进制为160),0XFFFF (十进制为65535)。 在程序中是根据前缀来区分各种进制数的 一般,不用8进制和16进制表示负整数,判断以下常量是否合法? 023 、23D 、029、 5A,2019/5/30,13,2、整数在内存中的存放形式-二进制补码,10,- 10,整数在内存中所占的字节数,取决于计算机系统中的机器字长。一般以一个机器字(WORD)存放一个int 数据。在微机中,一个整数以2个字节(16bit)存储。 因此,整型常数是有取值范围的。 (-32768+32767)10, (0017777
7、7)8,(0x00xFFFF)16,2019/5/30,14,如果使用的整数超过了上述范围,怎么办? 必须用长整型数(加后缀“L”或“l”)来表示。如 158L,0200000L,0X15L (十进制为21) 说明:158L和158 在数值上并无区别十进制长整数的取值范围:(-2147483648 2147483647)10,2019/5/30,15,无符号数:整型常数加后缀“U”或“u”。例如: 358u, 235Lu 。无符号数所占内存的字节数有符号数相同由于省去了符号位,能表示的整数范围不同十进制无符号整常数的范围为065535,2019/5/30,16,整型变量,1、整型变量的分类,2
8、019/5/30,17,2、整型变量的定义、运算变量说明的一般形式: 类型说明符 变量名标识符,变量名标识符,.; 例如:int a; long x,y; unsigned p,q; 整型变量的运算,2019/5/30,18,不同种类的整型数据可以进行数学运算main( ) int a,b,c,d; /*整型*/unsigned u; /*无符号整型变量*/a=12; b= -24; u=10;c=a+u; d=b+u;printf (“a+u=%d,b+u=%d”,c,d); 运行结果: a+u=22,b+u=-14,2019/5/30,19,3、整型量的溢出若一个变量无法容纳下要存入的数,
9、这种现象称为溢出,溢出将导致数据存储错误;在运算过程中也有可能产生溢出导致运算结果错,因此程序设计中应避免产生溢出。 例:int a, b1,b; /*int 范围-32768 32767*/a=65538; b1=32767; b=b1+1;/*= = 32768*/printf(“a=%d, b=%d“, a, b);输出 a=2, b=-32768 (溢出的错误结果),2019/5/30,20,溢出原因: 1) a=65538; 65538=(1 0000 0000 0000 0010 )2a: 只存入后16位 2) b=32768;32768=( 1000 0000 0000 0000
10、 )2b:-32768的补码,0000 0000 0000 0010,1000 0000 0000 0000,2019/5/30,21,解决办法:long a, b1,b;a=65538; b1=32767; b=b1+1;printf(“a=%ld, b=%ld“, a, b);a=65538, b=32768 (正确),2019/5/30,22,实型常量(浮点型常量),1、c语言中的实数有两种表示形式: 十进制小数形式 由数字09和小数点组成。 例如:.123、123.、123.0、0.0 (必须有小数点)指数形式 由尾数部分,字母e或E和指数部分组成。例如:123e3、0.15E-2。指
11、数形式注意:1)字母e或E之前必须有数字,e后面的指数必须为整数。如:e3、2.1e3.5、53.-E3都是不合法的指数形式。2)规范化的指数形式 如:2.34e2、3.099E5、,2019/5/30,23,实型变量,1、在内存中的存放形式: 实型数据在内存,按指数形式存储,即把数据分成小数部分和指数部分,分别存放。 如 3.14159,数符 小数部分 指数,2、实型变量的分类:,2019/5/30,24,3、实型变量定义 float x; double a,b; 4、实型量的舍入误差 由于实型变量占有限的存储单元,提供有限的有效数字。由此可能会产生一些误差。,例: /*赋值产生误差*/ f
12、loat a, b; a=123456.789e5; b=a+20; printf(“%f“, b); 输出12345678848.000000,float a; a=111111.111; printf(“i=%f”,i); 输出 111111.109375;,原因-float 只能接收7位有效数字, 后面的数字无意义),2019/5/30,25,字符常量,1、字符常量是用单引号括起来的一个字符。如A、a、?、3、=等 字符常量只能是单个字符,错误ab 5和5 是不同的。5是字符常量。 A、a是不同的字符常量。 2、转义字符,语言还允许用一种特殊形式的字符常量。 如 printf(“%d%d
13、n”,a,b) 其中,n 代表一个“换行”符,是一种“控制字符”,2019/5/30,26,转义字符:表示将反斜杠后面的字符转换成另外的意义,转义字符 含义 ASCII码 n 换行(将当前位置移到下一行开头) 10 t 水平制表(跳到下一个tab位置) 9 b 左退一格(将当前位置移到前一列) 8 r 回车不换行(将当前位置移到本行开头) 13 f 换页(将当前位置移到下页开头) 12 反斜杠字符 92 单引号字符 39 “ 双引号字符 34 ddd 1到3位8进制数所代表的字符 xhh 1到2位16进制数所代表的字符,2019/5/30,27,ddd和xhh分别是用八进制和十六进制的ASCI
14、I码表示一个字符。如 101(ASCII码为65)表示字符Ax41表示字符A 012(ASCII码为10)表示n(换行符)X0A表示换行 例:转义字符的使用 void main() int a,b,c; a=5; b=6; c=7; printf(“%dnt%d %dn ”,a,b,c); printf(“c:filedata”); ,56 7 c:filedata,2019/5/30,28,字符变量,1、字符变量的定义:char c1,c2; c1=a; c2=n; 2、字符变量的存储形式: 字符量占1个字节的存储空间,在存储单元中存放的不是字符本身,而是字符对应的ASCII码。 如存储a的
15、实际单元值是97,存放0的实际单元值是48。,97,a,48,0,01100001,00110000,2019/5/30,29,3、字符量的运算-字符量与整型量 字符数据以ASCII码存储(与整数的存储方式类似) 因此字符数据与整型数据之间转换非常方便。 1)一个字符既可以以字符或者整数形式输出 2)字符数据与整型数据可以相互赋值(注意: ASCII码的范围是0255) 3)字符可以像整数一样参加数值运算。,2019/5/30,30,例1 字符变量以字符形式和整数形式输出 main() char ch1,ch2; ch1=a; ch2=b; printf(“ch1=%c,ch2=%cn”,ch
16、1,ch2); printf(“ch1=%d,ch2=%dn”,ch1,ch2); 程序运行结果: ch1=a,ch2=b ch1=97,ch2=98,2019/5/30,31,例2字符数据参与算术运算。/*字母的大小写转换*/ main() char ch1,ch2; ch1=97; ch2=B ;printf(“ch1=%cn”,ch1-32);printf(“ch2=%dn”,ch2+32); 运行结果 ch1=Ach2=98,2019/5/30,32,字符串常量,字符串常量是用双引号括起来的零个或多个字符序列。如:“How do you do.”、”a”,”$123.45”,”。 a与
17、“a”有什么不同呢? C规定:每一个字符串的结尾都加一个0字符,作为 字符串的结束标志。即a与“a”的长度是不同的,在内 存中的存储是不同的:,1个字符 2个字符,2019/5/30,33,字符串“How do you do.” 在内存中的存储,其长度为15。 最后一个字符0,是字符串结束的标志,是系统自动加上的。 字符0是一个ASCII码为0的 “空操作字符”。即它不引起任何的控制动作,也不可显示。如果要输出字符串 “How do you do.”printf(“How do you do.”);,2019/5/30,34,变量赋初值,先定义后赋初值float x; int m,n; int
18、 m,n;x=5.6; m=3; n=3; m=n=3; 定义时赋初值float x=5.6; int m=3, n=3;char c1, c2=a; int a=13,b=5; int m=n=3; 错误,不允许在说明语句时,连续赋初值。,2019/5/30,35,三、各类数值间的混合运算,整型、实型、字符型数据可以混合运算:如 10 + a + 1.5 - 875.21 * b 运算规则:不同类型的数据先转换成同一类型,再进行运算。,2019/5/30,36,例:int i; float f; double d; long e; 10+a+i*f-d/e; 计算机执行运算的步骤: 1)10
19、+a:先将a转换成整数97,运算结果107 2) i*f:先将i与f都转换成double型,运算结果为double型 3)整数 107+ i*f :先将107转换成double型(107.000.00),结果为double型。 4)d/e:先将e转换成double型,运算结果为double型 5)第3步得到的double型减去第4步得到的double型,结果为double型 以上的类型转换是由系统自动完成的。,2019/5/30,37,小 结,常量整型、实型、字符型常量;字符串常量;符号常量(先定义后使用) 变量变量名(标识符);整型、实型、字符型变量;变量(先定义后使用) 掌握不同类型数据的
20、定义与存储特点,数据间的关系 掌握变量赋初值的方法 掌握不同数据类型间的混合运算规则,2019/5/30,38,基本运算符和表达式,C语言中有丰富的运算符和表达式,使C语言 的功能十分完善。C语言的运算符的特点: 不同的优先级-共分为15级1级最高,15级最低。 不同的结合性-分为左结合性和右结合性这种结合性是其它高级语言的运算符所没有的,因此也增加了C语言的复杂性。,2019/5/30,39,表达式中,运算的先后顺序: 要遵守运算符优先级别的规定 受运算符结合性的制约优先级较高的先进行运算;优先级相同时,按运 算符的结合方向处理 例如: 1)算术运算符的结合性是自左至右,即先左后右。表达式
21、x-y+z:先执行x-y运算;然后执行+z的运算。 2)赋值运算符“=”是最典型的右结合性运算符。表达式 x=y=z:先执行y=z,再执行x=(y=z)运算。 在学习过程中,要注意区别,避免理解错误。,2019/5/30,40,本节先介绍以下八类运算符: 算术运算符(+、-、*、/、%、) 自加自减运算符( +、- ) 赋值运算符(=,+=、-=、*=、/=、%=) 关系运算符(、=、=、!=) 逻辑运算符(&、|、!,3种) 强制转换运算符(数据类型) 条件运算符(?:) 逗号运算符(,),2019/5/30,41,一、算术运算符,1)% 要求两侧均为整型数据 5%2 =1,1%10 =1,
22、5.5%2 错误 2)两个整数进行 + - * / 运算,结果是整数。若参加运算的其中一个数是实数,结果为double型实数。5/3 =1,-5/3 = -1,5/3.0 =1.666667 3)“-” 也可作为“负号”,此时为单目运算符,优先级为2,右结合性,2019/5/30,42,作用是使变量的值增1或减1+i, -i (先执行i+1或i-1,再使用i值)i+, i- (先使用i值,再执行i+1或i-1),二、自增、自减运算符 + -,i=2; i=2; j=i+; j=+i;j的值为2 j的值为3i的值为3 i的值为3,2019/5/30,43,例1: int i=3;printf(“
23、%d”,i+); 输出3 ( i的值为4)int i=3;printf(“%d”,+i); 输出4 ( i的值为4),例2:int i=8 ;printf(“%d”,i+*2); 输出16(i的值为9)int i=8 ;printf(“%d”, + i*2); 输出18(i的值为9),2019/5/30,44,1)+,- -运算符只能用于变量,不能用于常量和表达式如5+,(a+b)- -,(-i)+都是不合法的 2)+,- -运算符的结合方向是自右至左。 3)表达式i+j 应理解为(i+)+j C编译系统在处理时,尽可能多地(自左而右)将若干个字符组成一个运算符。 4)当出现在函数实参中,如
24、printf(“%d,%d”, i,i+);求值顺序从右而左。i=3时,输出4,3,应该书写成:i=3;j=i+;printf(“%d,%d”, j, i);,2019/5/30,45,三、赋值运算符,结合方向:自右向左 优先级:14 简单赋值运算符 =变量标识符 = 表达式 作用:将一个数据(常量/表达式)赋给一个变量如 a=3; d=func( ); c=a+b; 复合赋值运算符 += -= *= /= %=,2019/5/30,46,复合赋值符这种写法,十分有利于编译处理,能提高 编译效率并产生质量较高的目标代码。,赋值表达式 表达式:用运算符和括号将操作数连接起来,符合c语法规则的式子
25、,称为表达式。如算术表达式 a*b/c+1.2-6%4, (a-b)*c, p+ 表达式的值 (注意:表达式代表的是一个数值)如 a=5(表达式的值为5,a的值为5)printf(“%d”,b=a); 输出5赋值表达式-“自右向左”结合赋值表达式 i=5 , c=a+3, a=b=5 相当于 a=(b=5),2019/5/30,47,赋值表达式可以包含赋值表达式a=5+(c=6)表达式的值为11,a的值为11,c的值为6 赋值表达式也可以包含复合的赋值表达式 赋值表达式 a+= a- =a*a (a=12) 求解过程: 先进行a-=a*a的运算相当于a=a-a*a=12-144=-132 再进
26、行a+=-132的运算相当于a=a+(-132)=-132-132 =-264,2019/5/30,48,赋值运算时的数据类型转换 原则: 1)被赋值变量的类型与表达式值的类型一致,直接赋值 2)不一致,系统自动以被赋值变量的类型为准进行转换,然后赋值。,例:int i=10, j, k; float f; double d;i=i-5; /* 5i */ j=i+3.56; /*8 j */k=a; /*97 k */f=23; /*单精度23.0 f */d=j+f; /*双精度31.0 d */,2019/5/30,49,3)具体规定如下:1.实型赋予整型时,舍去小数部分。2.整型赋予实
27、型时,数值不变,但将以浮点形式存放, 即增加小数部分(小数部分的值为0)。3.字符型赋予整型,由于字符型为一个字节, 而整型为二个字节,故将字符的ASCII码值放到整型量的低八位中,高八位为0。4.整型赋予字符型,只把低八位赋予字符量。 总之,字节少的数赋给字节多的变量时,高位自动进行符号扩展;字节多的数赋给字节少的变量时,高字节将被丢掉,2019/5/30,50,1. 关系运算符 (比较运算符) 六个: 大于= 大于或等于= 等于!= 不等于,6级、双目、自左而右,7级、双目、自左而右,四、关系运算符和关系表达式,2019/5/30,51,关系表达式 用关系运算符把两个表达式连接起来的式子如
28、: x3/2, a+1 表达式1、2的形式:算术、赋值、逗号、关系等任何C合法的表达式。关系表达式的值:逻辑值真、假真对应关系式成立,用整型量1代表;假对应关系式不成立,用整型量0代表;,2019/5/30,52,举例:说明下列关系式的含义 1) isqrt(c) 3) a%2=0例另外,注意区分“=”与“= =”int a=6,b,c;c=b=a;a=b=c;a的值为1,2019/5/30,53,举例:写出下列表达式的值 若有定义:int a=3, b=2, c=1; char ch1=a; 1) b+c!=a 2) ch1b)(bbbb=c 7) f=abc, 0, 1, 0, 1, 1,
29、 1, 0,2019/5/30,54,五、逻辑运算符和逻辑表达式,三种逻辑运算符 & | !,2019/5/30,55,逻辑运算的真值表 逻辑运算的值也为“真”和“假”两种,用1和0表示,如 5和3均为非“0”,5&3的值为“真”,即为15|0的值为“真”,即为1,2019/5/30,56,逻辑表达式 一般形式: 双目: 单目:! 表达式1 表达式1、2:任何C合法的表达式。 逻辑表达式的值:逻辑值真、假真条件成立,用整型量1代表;假条件不成立,用整型量0代表; 逻辑运算对象:0被视为逻辑量“假”;非0被视为逻辑量“真”。,2019/5/30,57,例1:a=3,b=4,c=5, 下列逻辑表达
30、式的值 a+bc&b= =c 1&0 为0 !(a+b)+c-1&b+c/2 0+5-1&4+2 为1说明:C在逻辑表达式求解时,并不一定是所有的 运算都被执行,当刚开始求解或求解的中途就可 以确定整个逻辑表达式的值时,其余的运算将不 再进行。 例:a&b&c 例:a|b|c,2019/5/30,58,例2:将所给条件写成C的逻辑表达式 1) 1a 8 并且 1 b 102) a和b都是正的或都是负的 (a、b符号相同)3) a和b之一为0,但不能都为04) a能被5或7整除,(a=1&a=1&b=10),(a0&b0)|(a0,(a*b=0)&(a+b!=0),(a%5=0)|(a%7=0)
31、,2019/5/30,59,六、强制类型转换运算符,(类型)(表达式) 优先级2 自右至左 将一个表达式转换成所需的类型如: (int)(x+y), (int)x+y , (double)(3/2) 说明:强制转换得到所需类型的中间变量,原变量类型不变。,main() float x; int i;x=3.6; i=(int)x; printf(“x=%f,i=%d”,x,i);,输出:x=3.600000,i=3,2019/5/30,60,总结:数据类型之间的转换,隐式转换(什么情况下发生?) 运算转换-不同类型数据混合运算时;int a=3, b; b=a+5.6; 赋值转换-把一个值赋给
32、与其类型不同的变量时; int a; a=5.6; 显式转换强制转换(float)a/2,(int)m % 3,2019/5/30,61,七、条件运算符(?:),结合方向:自右而左 优先级: 13 级 类型:三目 条件表达式一般形式: ? : 其中:各个表达式可以是任何形式的表达式。 求解过程: 如:ab ? a+2:b/6 先判断表达式1是否成立, 若成立则用表达式2的值作为整个条件表达式的值 否则用表达式3的值作为整个条件表达式的值。,2019/5/30,62, ? : ,2019/5/30,63,注意? : 1、表达式1、表达式2和表达式3的类型可以不同 若表达式2、3类型不同,则整个条
33、件表达式的 值应为二者中较高的类型。如:xy ? 1:1.5 若表达式1成立(真),表达式的值为1.0 若表达式1不成立(假),表达式的值为1.5 2、条件运算符的结合方向是自右至左如:ab ? a : cd? c:d 相当于ab ? a :(cd? c:d),2019/5/30,64,3、条件表达式可以实现简单的选择功能 例:输入一个字母,输出字母的小写形式。 思路:A-aa-a,main( ) char ch;scanf(“%c”, ,2019/5/30,65,例:printf(”%d”, ab ? a : b );例:求a、b、c中的最大值max=ab?a:b;max=maxc?max:
34、c;,2019/5/30,66,八、逗号运算符( ,),逗号除了可以作为分隔符使用之外,也可以 用逗号将若干个表达式分开便构成了逗号表达式。 一般形式:表达式1,表达式2,表达式n 结合性:从左向右 优先级: 15(最低) 逗号表达式的运算次序为:先求解表达式1的值,再求解表达式2的值, 最后求解表达式n的值。逗号表达式的值为表达 式n的值。,2019/5/30,67,如: (a = 3 * 5, a * 4) , a + 51)先求解 a = 3 * 5,得 a=15;2)再求 a * 4=60;(a的值仍为15)3)最后求解 a + 5=20,4)逗号表达式的值为 20。逗号运算符优先级最
35、低: 例:a=3*5, a*4 例:两个表达式的比较x=(a=3, 6*3) 18x, a:3x=a=3, 6*a x:3, 表达式的值为18,2019/5/30,68,逗号表达式常用于for循环语句。for(e1; e2; e3) 内嵌语句; for(i=0, j=10; i10; i+, j+) 并不是所有的逗号都是逗号运算符 int a,b,c; 变量声明间隔 printf(“%d,%d,%d”,a,b,c); 函数参数之间的间隔 printf(“%d,%d,%d”,(a , b , c),b,c); 红色逗号为逗号运算符,2019/5/30,69,小结,运算符优先级(从高到低) !(非) 2 算术运算符 3、4 关系运算符 6 、7 &和 | 11 、12 条件运算符 13 赋值运算符 14 逗号运算符 15,低,高,结合方向 自右向左 自左向右 自左向右 自左向右 自右向左 自右向左 自左向右,2019/5/30,70,习题 3.3 (1)(5)3.6、 3.7、3.9、3.12 (1 3 5 6) 上机实验2 1、从键盘输入公里数,屏幕输出其对应的英里数。已知1英里1.60934公里。(要求:用符号常量。) 2、从键盘输入3个数,使用条件表达式求出它们的最小值并输出其值。,