《第3章基本数据类型与数据运算.ppt》由会员分享,可在线阅读,更多相关《第3章基本数据类型与数据运算.ppt(33页珍藏版)》请在三一办公上搜索。
1、第三章 基本数据类型与数据运算,C语言支持的数据类型及类型名称和机器内表示各类型常量的表示、变量的定义及变量的访问类型转换与格式化输出C语言运算符和表达式,5U 5-12-12L 3.14 5.0 a“abc”a”C语言支持哪些数据类型?如何定义?如何存储?各类型的常量和变量如何表示?,3.2 数据类型,C中没有bool型(逻辑型),进行逻辑运算时零代表假,非零代表真,整型:,无符号数直接转换为二进制存储,高端补0;有符号数存储补码,实型:参照IEEE754标准,字符型与字符串常量:,字符型常量是用单引号括起来的单个字符,如char c=a,a=a字符型变量的内存单元中实际存放字符的ASCII
2、码,如上例存97由于字符型数据实际对应一整数,故字符型与整型有时可通用:int i=a;char c=97;int j=a-32;char b=c-32;数值范围的理解:有符号字符型-128到127,无符号0-255,3.3 常量与变量,常量:程序运行过程中不可变的量,整型 5-12 010-010 0 x2-0 x2F 50U-123L 实型 3.14 12.5 12.3e3-1E4 2.3f字符型a A 2$n 101 x2A字符串“study hard!”“a”,整型默认为signed int型,后加U或L可改变类型;有十/八/十六进制三种写法实型默认为double型,后可加f指定为fl
3、oat型,分小数形式和指数形式两种;指数形式表示时E或e前不能空,e后为整数字符型常量默认为signed char;分普通字符和转义字符两种.具体看书自学字符串常量是”括起来的串,末位自动添加结束符0,务必区分A与”A”注意:-32768U与-32768在寄存器中存储结构一样,均为FF FF 80 00。区别在于,设有Unsigned x;则x=-32768会有警告,而x=-32768U无警告,3.3 常量与变量,符号常量:用标识符代替一个常量(给常量起名),#define PI 3.14#define TRUE 1#define FALSE 0#define OK 1#define ERRO
4、R 0#define NULL 0,#include#define PRICE 30void main()int num,total;num=10;total=num*PRICE;printf(total=%dn,total);,使用目的:见名知意,一改全改标识符命名规则:由字母、数字和下划线组成,以字母和下划线开头,不能与系统保留字(3.1)重名。通常不多于8个字符。不仅符号常量名,变量名和函数名亦遵循此规则规范:符号常量名通常全部大写,变量名和函数名首字母小写,若由多个单词组成则剩余单词首字母大写。注:符号常量在编译阶段直接被替换为所代表的常数,不为其分配内存,不能赋值。符号常量定义语句后
5、无分号,3.3 常量与变量,变量:程序运行中值可变的量。,注:变量实际对应内存中一个内存块,块大小由变量类型决定,根据变量名可找到对应的内存块注:为变量赋值就是根据变量名找到相应内存块,之后将数据(位于累加器)写入其中;取变量的值就是通过变量名找到相应的内存块,从中读取数据到CPU命名规范:遵循标识符命名规则,最好见名知义注:必须先定义后使用;一次可定义多个同类型的变量;使用前通常赋初值,可定义同时赋值(如int i=0),short flag;int i,j,k;long factorial;unsigned count;,float x,y;double average;,char c;u
6、nsigned char a;,作业说明:,求最大最小值辗转相除级数求和素数+Fibnacci数列+回文+水仙花数?,回顾:,掌握各种常见语法错/连接错/运行错和逻辑错及其原因通过编译信息能发现和改正语法错,理解测试的重要性,能合理组织测试数据并通过测试完善程序了解断点的概念和作用了解C语言支持的数据类型,掌握整型、实型和字符型数据的分类及各自的类型名称,熟练掌握各自的存储表示掌握各类型常量的写法与默认类型符号常量的定义和使用变量的定义,变量的赋值和使用,整型默认为signed int型,后加U或L可改变类型;有十/八/十六进制三种写法实型默认为double型,后可加f指定为float型,分小
7、数形式和指数形式两种;指数形式表示时E或e前不能空,e后为整数字符型常量默认为signed char;分普通字符和转义字符两种,如101 x2A字符串常量是”括起来的串,末位自动添加结束符0,务必区分A与”A”,3.4 基本数据类型的转换,自动类型转换:某些类型的数据一旦参与运算(即进入CPU寄存器时),或者不同类型的数据进行混合运算时,数据类型就会发生自动转换,称之为自动类型转换转换规则:范围小到大,等值转换(不同编译器规则不尽同,VC如下)unsigned char/short进CPU自动转为unsigned int;【高位补零】signed char与short进CPU时自动转换为等值i
8、nt;【符号位扩展】float进CPU直接转为double;【指数部分与尾数部分分别扩充】无论哪种整型与double型混合运算,整型均转为等值double型 其余:类型长短不一时,以较长的为准,长度相同时,有符号的转化为无符号的,如32767+1L结果32768L;再如a=-1L;b=1U;则ab例:234-b+26.5,3.4 基本数据类型的转换,强制类型转换:通过类型转换语句显式进行转换(目标类型)(变量或表达式),注:对变量进行强制类型转换时只是在CPU寄存器中对变量值作临时转换,变量类型及其在内存中的数据保持不变,如以下语句执行后x仍为float型,值仍然为3.5:float x=3.
9、5;int i=(float)x;注:假设float x=3.5,y=3.5;则(int)x+y为实数值6.5;而(int)(x+y)值为7,#include void main()printf(%dn,(int)3.5);printf(%dn,(int)-3.5);printf(%lfn,(double)3);printf(%lfn,(double)-3);printf(“%lfn”,5/3);/不匹配,结果错printf(%lfn,(double)5/3);/注:printf(“%lfn”,1)输出0.000000,double型值=float变量:指数部分与尾数部分分别截取,转换成十进制
10、相当于截取其前7位有效数字double值=整型变量:舍弃小数部分,存整数部分整型数据=实型变量:以等值的浮点数形式存储各类整型、字符型之间:先将右侧值读入寄存器(遵循前述自动类型转换规则,VC下内存位数不足4字节者均扩展成4字节,有符号数按符号位扩展,无符号数作零扩展。TC下字符型扩充成2字节),之后截取相应数目的字节放入左侧变量空间,补充:不同类型数据间的相互赋值,char c1,c2;/以下是VC下过程分析,TC下将下划线部分去掉c1=300;/R(300)=0 x00 00 01 2C;M(c1)=0 x2Cc2=400;/R(400)=0 x00 00 01 90;M(c2)=0 x9
11、0printf(“%c%cn”,c1,c2);/R(c1)=00 00 00 2c,/R(c2)=ff ff ff 90;截取末字节,VC输出,?;TC输出,printf(“%d%dn”,c1,c2);/R(c1)=00 00 00 2c,/R(c2)=ff ff ff 90;分别是44和-112补码,输出44与-112,补充:格式化输出函数printf说明,正常情况:格式控制符%d用于输入输出有符号整型数,%u用于无符号整型数,%X或%O以十六或八进制输出各类整型;%f用于float,%lf用于double,%c用于char原理说明:输出值先进入寄存器(可能要扩充),以c输出则截取寄存器最末
12、一字节输出其对应的字符;以d输出意味着将寄存器中的数据当作signed int的补码,输出此补码对应的真值;以u输出意味着将寄存器中的数据当作一个unsigned int,直接转换为十进制数后输出;以X输出则将寄存器中的二进制数从低到高四位合一位输出,高位零省略;以O则三位合一位输出,short a;unsigned short c;short e;/以下VC下分析,TC去下划线a=100;/*R(100)=0 x00 00 00 64;M(a)=0 x00 64*/e=50000;/*R(50000)=0 x00 00 C3 50;M(e)=0 xC3 50*/c=a=e;/*R(e)=0
13、x ff ff C3 50;M(a)=0 xC3 50*/*R(a)=0 xFF FF C3 50;M(c)=0 xC3 50*/printf(“%dn”,a);/*R(a)=0 xFF FF C3 50;输出-15536*/printf(“%u n”,c);/*输出50000*/printf(“%xn”,a);/R(a)=0 xFFFFC350,VC:ffffc350,TC:C350printf(“%o n”,c);/*R(c)=0 x00 00 C3 50;输出141520*/,作业1:分析如下程序的执行过程与输出结果(似前例,参考作业说明),#includevoid main()shor
14、t a,b;unsigned short c,d;long e,f;a=100;/*R(100)=(00 00 00 64)16,截取得M(a)=(00 64)16*/b=-100;e=50000;f=32767;c=a;d=b;printf(“%d,%dn”,a,b);/*R(a)=(00 00 00 64)16,是100的补码;R(b)=/(ff ff ff 9C)16,是-100的补码,输出100,-100*/printf(“%u,%un”,a,b);printf(“%u,%un”,c,d);c=a=e;d=b=f;printf(“%d%dn”,a,b);printf(“%u%un”,c
15、,d);printf(“%x%Xn”,a,b);printf(“%o%on”,c,d);,3.5 运算符和表达式,表达式:运算符和运算对象按一定规则结合在一起形成的式子记:表达式具有值(运算结果)和类型,如3*5值为15,类型为int,3.5.2算术运算符和算术表达式,算术运算符:+-*/%(双目)+-(单目)除运算符/:分子分母均整型时是整除.取余运算符%:操作数均整型方可,否则编译错.分子分母有负数时,先求绝对值之商,后根据分子定符号:15%4为3;15%(-4)为3;(-15)%4为-3;(-15)%(-4)为-3自增运算符+:变量自增运算符,操作对象必须为变量,如x+或+x,但(x+y
16、)+错。x+是先用后增,先将变量的值读入寄存器参与运算,当前语句结束后再将内存中x的值增1;+x先增后用,先将内存中变量值增1后进入运算器参与运算自减运算符-:类似自增运算符,只是变量减小1运算符+-均单目运算符,优先级高于其它算术运算符,且均为右结合。如i=3;j=-i+;相当于j=-(i+);算术表达式:用括号、算术运算符和运算对象连接起来的符号C语法规则的式子,int x=3,y;y=(x+)+(x+)+(x+);printf(nx=%d,y=%d,x,y);,int x,y,a,b,c;x=3;a=x+;b=x+;c=x+;y=a+b+c;printf(nx=%d,d=%d,x,y);
17、,作业2:,3.3:1 3 5 6提示:开平方根函数为sqrt,如求变量x的平方根赋值给y,可写作y=sqrt(x),注意头文件包含与变量类型,回顾:,自动类型转换与强制类型转换不同类型相互赋值规则:double-float double-整型整型-实型 各整型、字符型之间格式化输出常规用法与输出原理算术运算符/%+-注意事项与优先级和结合性其它运算符与常见函数,3.5.3赋值运算符与赋值表达式,赋值运算符:简单赋值运算符=;复合赋值运算符+=*=等 如:x=3;x+=3相当x=x+3;x%=y+3相当x=x%(y+3)不同类型的赋值:double-float double-整型 整型-实型
18、各整型、字符型之间注:赋值语句右侧可为任意表达式,左侧必须为变量注:赋值表达式类型与值取决于左侧变量.如 char c;printf(“%d”,c=400);显示-112.注:赋值表达式可作变量用,相当于左侧变量,如(a=3*5)=4*6可,a=3*5=4*6错注:赋值语句具有右结合性。优先级比常见运算符都低 char c;i=c=259;a=(b=4)+(c=6)a+=a-=a*a相当于a=a+(a=a-a*a);赋值表达式不同于赋值语句,printf(“%d”,i=3);合法,而printf(“%d”,i=3;);不合法,关系运算符及其优先次序:=!=,格式:如 30 x0 i=0 x!=
19、y注:关系运算成立时结果为1,不成立时结果为0。注:=是判断相等,=是赋值,前者返回0或1,后者返回左侧变量值。C语言中判断一个量时认为零为假,非零为真。如if(i=0)printf(“Never Visible!”);if(i=0)printf(“Visible if i equals zero!”)if(i=1)printf(“Always visible!”);if(i=1)printf(“Visible if i equals one!”)注:左结合,优先级整体上低于算术运算符,高于赋值运算符。内部而言,=和!=低于其它=等其它关系运算符,3.5.4关系运算符与关系表达式,关系表达式:
20、关系运算符将两个表达式(类型任意)连接起来的关系式.如a+bb+c,(a=3)(b=5),ab=c,a=bc,532,#includevoid main()int a=123,b=234,c=345,d=456;int t1,t2,t3;t1=ab;t2=c!=d;t3=a=c-d;printf(t1=%d,t2=%d,t3=%dn,t1,t2,t3);,逻辑运算符:!(逻辑非)&(逻辑与)|(逻辑或),格式:如x0成立则表达式值1,否则值为0.结合性与优先级:左结合(!除外).!与单目算术运算符 双目算术运算符 关系运算符&|赋值运算符,3.5.5 逻辑运算符和逻辑表达式,逻辑表达式:用逻辑
21、运算符将表达式连接起来的式子。注意C语言中只要值非零就认为是真,零就认为是假,a=4,b=5,c=6时:!a值为0 a,“短路运算”说明:,在逻辑表达式的求解中,并不是所有的逻辑运算符都要被执行。(1)a&b&c 只有a为真时,才需要判断b的值,只有a和b都为真时,才需要判断c的值。(2)a|b|c 只要a为真,就不必判断b和c的值,只有a为假,才 判断b。a和b都为假才判断c,例:设a=1;b=2;c=3;d=4;m=1;n=1;则经(m=ab)&(n=cd)后,m的值为0,而n的值仍为1。,格式:表达式?表达式表达式功能:表达式1成立吗(非零),成立则结果为表达式2的值,否则结果为表达式1
22、的值如:max=ab?a:b;或 min=ab?a:b;,补充:(1)优先级:条件运算符优先级仅比赋值运算符高(2)结合方向:自右至左,同赋值运算符和单目运算符,如ab?a:cd?c:d理解为ab?a:(cd?c:d)(3)条件表达式还可是赋值表达式或函数表达式,如:x0?y=x:y=-x;x0?printf(“%d”,y=x):printf(“%d”,y=-x);(4)三个表达式的类型可各不相同,返回值类型为后两个表达式中较高的类型,如xy?1:1.5;当xy时返回1.0,3.5.6 条件运算符与条件表达式,功能:顺序“计算”各表达式,整个式子的值和类型取决于最末一个表达式优先级和结合性:左
23、结合,优先级最低,格式:表达式,表达式,表达式例:i1,sum=0,例:比较 printf(“%d”,x=(3,6*3)与 printf(“%d”,(x=a=3,6*3);,3.5.7 逗号运算符和逗号表达式,说明:逗号表达式最常用于for循环中。如 for(i=1,sum=0;i=100;+i)sum=sum+i;,3.5.8位运算符与位表达式,自学:一要掌握各种位运算的运算规则;二要掌握各种位运算的用途自学不一定不考!要注重自学能力的培养,充分利用各种学习手段!,3.5.9 取长度运算符,格式:sizeof(类型名或表达式)功能:返回指定类型或者表达式类型在内存中所占字节数如:sizeof
24、(short)值为2;sizeof(int)在VC下值4,TC下值2;sizeof(3.0)值8;sizeof(x)由变量x类型定,若x为float型,则值4,运算符的优先级和结合性,说明:P89表3.9中部分运算符尚未学,总结常见运算符的优先级和结合性规律即可优先级:单目(+-!)算术 关系 逻辑 条件 赋值 逗号结合性:单目运算符与三目运算符是右结合,双目运算符中仅赋值运算符是右结合,其余左结合,3.6 应用举例,例3.27 设k4 k5 k6 k7各变量初值均为10;则经过语句k4+=k5-=k6*=k7/=2;各变量值为多少?依次为:-30-40 50 5例3.28:分析运行结果,#i
25、nclude void main()int a,b,c,d;a=1188!(8866-!99);c=1122%3/运行结果:a=1,b=1,c=1,d=0,3.6 应用举例,例3.29:分析程序运行结果t是跳到从当前位置开始的下一个水平制表位。所谓水平制表位是指屏幕上的第1列、第9列、第17列等8*i+1列;b相当于键盘上的backspace键,它将会删除当前光标位置前的一个字符。但是,若当前光标前是一个t,则将此t产生的空格一次性都删除。,#include void main()char x,y,z,s;x=p;y=m;z=n;s=376;/*376代表的字符非标准ASCII码字符,输出不定
26、*/printf(%c%c%c%cn,x,y,z,s);printf(%ct%ct%ct%cn,x,y,z,s);printf(%cn%cn%cn%cn,x,y,z,s);,3.6 应用举例,例3.30 分析程序运行结果,#include void main()int x,y=66;float f=12.3;x=(int)f+88+-y*66;printf(x=%d,y=%d,f=%fn,x,y,f);输出结果:x=4390,y=65,f=13.300000,教材问题说明:,上课认真听,课下抓紧回顾以下为已发现之问题,不代表全部,作业1答案:,#includevoid main()short
27、a,b;unsigned short c,d;long e,f;a=100;/*R(100)=(00 00 00 64)16,截取得M(a)=(00 64)16*/b=-100/*R(-100)=(ff ff ff 9C)16,截取得M(b)=(ff 9C)16*/e=50000/*R(50000)=(00 00 C3 50)16,得M(e)=(00 00 C3 50)16*/f=32767;/*R(32767)=(00 00 7f ff)16,得M(f)=(00 00 7f ff)16*/c=a;/*先将a读入寄存器得R(a)=(00 00 00 64)16,后截取得M(c)=(00 64)
28、16*/d=b;/*先将b读入寄存器得R(b)=(ff ff ff 9C)16,后截取得M(d)=(ff 9C)16*/printf(“%d,%dn”,a,b);/*先将a读入寄存器得R(a)=(00 00 00 64)16,这是100的补码;同样,将b读入寄存器得R(b)=(ff ff ff 9C)16,这是-100的补码*/printf(“%u,%un”,a,b);/*先将a读入寄存器得R(a)=(00 00 00 64)16,以u输出意味着将寄存器中的数据当作一个无符号的二进制数,将其直接转换为十进制数后输出,(00 00 00 64)16按位权展开求和后得100;而R(b)=(ff f
29、f ff 9C)16,转换为十进制得4294967196*/printf(“%u,%un”,c,d);/*注意c与d为无符号变量,读入寄存器时扩充零,将c读入寄存器得R(c)=(00 00 00 64)16;而R(d)=(00 00 ff 9C)16,转换为十进制得65436*/c=a=e;/*R(e)=(00 00 C3 50)16,截取得M(a)=(C3 50)16,R(a)=(ff ff C3 50)16,截取得M(c)=(C3 50)16*/d=b=f;/*R(f)=(00 00 7f ff)16,截取得M(b)=(7f ff)16,R(b)=(00 00 7f ff)16,截取得M(
30、b)=(7f ff)16*/printf(“%d%dn”,a,b);/*R(a)=(ff ff C3 50)16,此补码对应真值为-15536;R(b)=(00 00 7f ff)16,此补码对应真值为32767;*/printf(“%u%un”,c,d);/*R(c)=(00 00 C3 50)16,转为十进制得50000;R(d)=(00 00 7f ff)16,转为十进制得32767;*/printf(“%x%Xn”,a,b);/*R(a)=(ff ff c3 50)16,以x输出则将寄存器中的二进制数从低到高四位合一位进行输出,得ffffc350;R(b)=(00 00 7f ff)16,以X类似得7FFF。注意高位的零省略*/printf(“%o%on”,c,d);/*R(c)=(00 00 C3 50)16,以o输出则将寄存器中的二进制数从低到高三位合一位进行输出,得141520;R(d)=(00 00 7f ff)16,输出77777注意高位的零省略*/,