C语言第3章(谭浩强).ppt_第1页
C语言第3章(谭浩强).ppt_第2页
C语言第3章(谭浩强).ppt_第3页
C语言第3章(谭浩强).ppt_第4页
C语言第3章(谭浩强).ppt_第5页
已阅读5页,还剩72页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1,第三章 数据类型、运算符 与表达式,2,3.1 C 的数据类型,算法处理的对象是数据,而数据是以某种特定的形式存在的。所谓数据结构指的是数据的组织形式。 所有的程序设计必需有两个问题待解决: 1、数据描述 2、操作步骤 就象厨师做菜一样,没有原材料就无法做出菜来。在C语言中编程序也是要先定义数据常量、变量,与PASCAL相同,其主要原因是在内存中事先预留出地方以便使用。,3,4,3.2 常量与变量,一、常量和符号常量: 常量:在程序运行的过程中,不能被改变的量称为常量。 整型常量:12、0、-8 实型常量:4.6、1.23、-0.9 字符型常量:a、B、 其中为定界符,而不是字符型常量的一部分。 也可以用一个标识符代表一个常量,5,如:P38例3.1 符号常量:#define PRICE 30,这是一种编译预处理,叫做“宏定义”。指定PRICE代替30,在以后的程序中遇到PRICE即用30代替,这种用一个标识符代表一个常量,称为符号常量。它不属于C语句,所以不必在末尾加上“;”。其作用域在文件结束或遇# undef处结束。 一般格式为:# define 符号常量 常量 优点:含义清楚、改动方便,6,二、变量:,在程序运行过程中,其值能被改变的量。一个变量有一个名字,占一定的存储单元,在该存储单元中存储变量的值。(如在教室上课的学生) 1、每个变量都有两个特点:一是变量的名字;二是每个变量值都占据一块内存单元。 如:P39图3-1 变量名 变量值 教室名 学生 a 3,7,和其它语言一样,所有变量名、符号常量名、函数名、数组名、类型名、文件名的有效字符序列被称为标识符(identifier)。 C语言规定标识符只能由字母、数字、下划线三种字符组成,且第一个字符必须为字母或下划线。,8,2、变量起名原则:,变量所起的名字不可与32个保留字重名 必须以字母或下划线开头,由字母、数字或下划线组成的长度为8的字符串。(Turbo C允许有32个字符) 例:有两个变量,student-name和 student-number,因二者的前八个字符相同,所以系统认为它们是一个变量。 应本着见名知义的原则。常见初学者有起a1,b,a2等等。名字虽不影响程序的运行,但可读性不好,或起成app_num,可以猜到是表示苹果数。,9,大写字母与小写字母意义不同,被认为是两个不同的字符。一般变量名用小写字母表示。 注意:常量名常用大写、变量名常用小写! year Day a_12 _abcdef #123 .com $100 1999Y a=b 1_2_3 +abcedfghi -5 等,10,3、变量要先定义后使用,要用到的变量,必须先对其进行定义,才可以使用。如果是未经定义的变量,在编译时会检查出来。 定义变量时指定变量的类型,在编译时准备为其分配相应的存储单元。另外,还可在编译时检查该变量所做运算是否合法。 如:int a,b,c;,11,3.3 整型数据,一、整型常量的表示方法 1、十进制整数:239、-103等。每个数位都可以是0-9。 2、八进制整数:以0开头, (128)10 =0200 。即(200)8每数位都可以是0-7。 -011表示十进制-9。 3、十六进制整数:以0x开头, (291)10=(123)16 。每数位都可以是0-9、A-F。 注:1、二进制、八进制、十六进制转换成十进制方法:按权相加 2、十进制转换成二进制、八进制、十六进制方法:连续除以基数,从低到高记录余数,直至商为0,12,二、整型变量,1、整型变量在内存中的存放形式: 数据在内存中是以二进制形式存放。 每一个整型变量在内存中占两个字节。 如:int i=10; 在计算机基础中应该学过补码,数值在内存中应以其补码形式存放的。而正数的补码和其原码相同。负数的补码是按位取反再加1。 例如10、-10: 10的补码和-10的补码: 十进制数10 的二进制形式为1010,,13,14,2、整型变量的分类,根据数值的范围,整型变量类型分为: 1)基本整型,以int表示 2)短整型,以short表示 3)长整型,以long表示 在C中,为了更精确描述整型数据,又进一步分为六种类型,区别主要是在表示整数的范围不同。具体见下表:,15,16,=32767,有符号整型:,符号位,无符号整型:,=65535,数据位,见P43图3-5,17,3、整型变量的定义,int a,b;(定义两个整型变量a和b) unsigned short c,d,f ;(定义三个无符号短整型变量c、d、f) long e;(定义一个长整型变量) 格式应为: 变量1,变量2,变量3变量n; 一般应在函数一开始就进行定义。 例如下列程序:,18,void 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=%dn”,c,d); 运行结果:a+u=22,b+u=-14 结论:不同类型的整型数据可以进行算术运算。,19,4、整型数据的溢出,在运算的过程中,若变量的值超过该类型的范围,则会产生溢出。 例:void main( ) int a,b; a=32767;b=a+1; printf(“%d,%d”,a,b); 运行结果为:32767,-32768,20,把变量b改为long型,a+1改为a+1L,并用%ld格式输出,即可得b为32768,21,三、如何判断整型常量的类型,若在-3276832767之间,可认为是int或short型,long型。 若超出了-3276832767,而在 -2147483648+2147483647之间,则认为是long。若认为是int类型的,系统不做检查,但数据会丢失。,22,如果使用的C语言版本分配给short和int数据的长度相同,则可以互相赋值给变量; 针对常量unsigned型,一个非负值的整数可以赋值给unsigned型变量,注意其范围。50000可赋给unsigned int型,70000却不可以。为什么? (无符号整型变量最大值 65535.) 如一整型常量后有U或u,则认为是unsigned int,例如123u在内存中按unsigned int的方式存放和参加计算的; 如一整型常量后有L或l,则表示为long int型的。如123L。常用于函数的调用中。,23,一、浮点型常量的表示方法,1、十进制小数形式: 由整数部分、小数点和小数部分组成。 例如:1.24 0.345 234.0 0.0 等。 2、指数形式:由实数部分、指数部分、E(e)组成。用于表示一些比较大、比较小的数值。,3.4 浮点型数据,24,2、指数形式,例如:123*1022=123E22 注意:E之前必须要有数字,E之后数字必须为整数。 e12 4.4e1.5 .e5都是不合法的。 对于123.456有以下几种表示方法: 123.456e0 12.3456e1 1.23456e2 0.123456e3 0.0123456e4 0.00123456e5等。 其中1.23456e2为“规范化的指数形式”。 其小数点前只能有一位非零的数字。,25,二、浮点型变量,一个浮点型数据在内存中占4个字节、32位。 1、浮点型数据在内存中的存放形式 与整型数据不同,浮点型数据是按照指数形式存储的。系统把数据分成小数部分和指数部分,分别进行存放。 如3.1415926的存放,实际上,计算机是用二进制存放数据,而浮点型数据占4个字节(32位),其中多少位存放小数部分,多少位存放指数部分并没规定,但一般C的编译系统用24位存小数和符号,用8位存指数。 存放小数部分的位数越多,有效数字越多。而存放指数部分的位数越多,能表示数值的范围越大。,26,2、浮点型变量的分类,以上的有效位数和数值范围适用于Turbo C、Turbo C+、MS C,不同系统会有差异。,27,3、浮点型数据的舍入误差 由于浮点型变量的存储单元是有限的,所以超过有效位的数字会被舍去,由此就会产生误差。,例3.4:,void main( ) float a,b; a=123456.789e5; b=a+20; printf(“b=%f”,b);,结果为:b=12345678848.000000 结果为:x=7.123456954956054690,void main( ) float x; x=7.1234567890; printf(“x=%.18f”,x);,28,这就说明,一个浮点型常量赋值给一个浮点型变量时,只根据浮点型变量表示的有效数字的位数,在浮点型常量中按从左向右的方向截取数据。float型的变量只能保存7位有效数字,double型的变量只能保存15-16位有效数字。,29,三、浮点型常量的类型,一个浮点型常量可以赋给一个float型、double型、long double型的变量,系统根据变量的类型截取实型常量中有效的数字。C语言编译系统一般将浮点型常量作为double型来处理。例如:float a; a=111111.111(最后两位没有意义,可以改为double型) void main( ) float x;double y; x=123456.789;y=123456.789; printf(“%f, %f”,x,y); 结果为: 123456.789062, 123456.789000,30,3.5 字符型数据,一、字符常量 1、在C语言中字符型常量是用单引号括起来的一个字符。 如:a、A、3、?、 、$等。 2、以“”开头的转义字符,如n不代表字母n,而是代表换行。,31,如:101。八进制101等于十进制65,根据ASCII码表得出101代表字母A,32,例 转义字符的使用,main( ) printf(“ ab ct derftgn”); printf(“htibbjkn”); 运行结果: f gde h jk,33,二、字符变量,一个字符变量只能存放一个(不能是字符串)字符常量 char c1,c2; c1=a;c2=b; 在内存中占一个字节的空间。,34,三、字符数据在内存中的存储形式,系统在表示一个字符数据时,并不是将字符本身的形状存入内存,而只是将字符的ASCII码存入内存。在内存中所有的数据又是以二进制的形式存放的。 如P50图3-8 例如字符a的ASCII码为97,b的ASCII码为98。,35,例如3.6:向字符变量赋予整数 void main( ) char c1,c2; c1=97;c2=98; printf(“%c,%cn”,c1,c2); printf(“%d,%dn”,c1,c2); 结果为: a,b 97,98 说明:字符型数据和整型数据是通用的,但是字符型只占一个字节,只能存放0255内的整数。,36,例3.7 大小写字母转换 #include Void main() Char c1,c2; c1=a; c2=b; c1=c1-32; c2=c2-32; Printf(“%c %c”,c1,c2); 结果:A B,37,例如:整型和字符型变量可以相互赋值: main( ) int i;char c; i=a; c=97; printf(“c= %c, c= %dn”,c,c); printf(“i= %c, i= %dn”,i,i); 执行结果为: c= a ,c= 97 i= a ,i= 97 结论:一个字符型数据,既可以字符形式输出,也可以整数形式输出。也就是字符型和整型数据可以进行换算。但是字符数据只占一个字节,它只能存放-128-127范围中整数。,38,说明:TC中将字符变量定义为signed char型,所以存储单元中的最高位应该为符号位,那么它的取值范围就是-128-127(一个字节),在用%d格式输出时,ASCII码在0-127之间的会输出一个整数。如果字符变量中存放的是ASCII码在128-255之间的字符,会得到一个负数。例如: main( ) char c=130; printf(“%d, ”,c); 结果为:-126 解决办法:可以把字符变量定义为unsigned char型,其取值范围是0-255.,39,四、字符串常量,字符串常量是由双引号括起来的字符序列。 如:“how do you do”, “CHINA”, “a”, “4+3”, “$134323.54” “a”和a是不同的。 究竟区别在哪里呢? 在C中,每一个字符串常量的结尾处系统会自动加一个“字符串结束标志”(0,它占一个字节的宽度)表明字符串结束。 所以: a在内存中只占一个字节的宽度,而“a”在内存中占两字节的宽度。,40,字符串变量,在C语言中没有专门的字符串变量来存放字符串常量,须用字符数组来存放。这将在第7章 数组中介绍。 关于变量的总结: int a,s; 整型 float x,y; 实型 char c,d; 字符型,41,3.6 变量赋初值,程序中常需要对一些变量预先设置初始值。,42,一、什么是对变量赋初值,(C语言允许在定义同时赋初始值)。变量赋初值就是在定义变量的同时,给变量赋一个值。这个变量产生后第一次被赋值,所以叫赋初值。 如:int a=3; float x=5.56; char c1=a;,43,二、如何进行赋初值,对变量赋初值只要在定义的时候用赋值运算符赋给该变量一个值就行。 例如:int m=1, x=3; float y=4.6; char z=a;,44,三、在赋初值过程中的问题,1、可以把变量的一部分赋初值;如 int x,y,z=3; 注意:此时只有z=3,而x,y没有初值,其初值也不是0,而是一个不确定的值,这个值在该变量所能表示的数值范围内,具体是多少我们不知道。如果此时使用该变量,系统不会检查、提示,而直接使用其中那个不确定的值,会出错的。 如:int x,y,z=3; 相当于如下两个语句: int x,y,z; z=3;,45,三、在赋初值过程中的问题,2、如果给几个变量赋同一个值; int a=b=c=3;这种写法是不正确的。不能表示a、b、c的初值都是3。 可写成: int a=3,b=3,c=3; 或者: int a,b,c; a=b=c=3; 注意:初始化不是在编译阶段完成的,而是在运行时赋予初值的。,46,3.7 各类数值型数据间的混合运算,一、为什么各类型的数据可以进行混合运算 我们前面已经讲过,字符型数据在内存中是按数值方式存放的。而整型数据和实型数据肯定也是按数值方式存放的。在这种前提下,这三种类型的数据实际上是可以进行混合运算的。就象生活中,3块5再加2块一样(这里说的是人民币3.5元加2元)。但是应该有一个运算原则。,47,二、如何在各类型的数据之间进行混合运算,我们已经知道,不同类型的数据可以进行混合运算,但是还要遵循一个原则: 在运算过程中,不同的数据类型要先转换成同一类型后,才能进行运算。转换规则在书中P54图3-10。 在类型转换图中,级别越高的类型,它在内存中占的字节数越多。,48,1、水平向左箭头:这种水平方向上的转换是在任何时候都要进行的,就算两个char类型的数据进行运算,也要先转换成整型数据再运算 2、竖向箭头:在进行了水平方向上的转换后,如果仍然存在不同类型的数据,就要进行纵向的类型转换。转换方向为由下向上,由低级向高级靠拢,运算结果的类型和式子中最高级别的类型是一样的。如两个类型的最高型是long,低的类型就要转换为long型。,49,例如:int和double的数据进行运算,那么要将整型数据转换为双精度型数据后再进行运算。运算结果将是双精度型的数据。(注意:int直接转换成double,中间的类型跳过),50,例: int i; float f; double d; long e; 10+a+i*f-d/e 所有的类型转换过程都是由系统自动进行的。,51,3.8 算术运算符和算术表达式,1、C算术运算符 + 加法运算符或正值运算符 - 减法运算符或负值运算符 * 乘法运算符 / 除法运算符 % 模运算符或称求余运算符,52,注意: 1、 使用“/”时注意:如果运算符两边的数据为整型,那么得到的结果也必是整型,5/2=2,1/5=0,而不是0.2,1.0/5=0.2。另外,如果其中一数是负数,舍入的值不固定,得到的值也不固定。如:-5/3可以得到-1和-2两值,TC2.0采取“向零取整”法得到-1。 2、 使用“%”时注意:该运算符的两边只能是整型数据。如:7%4的数值为3。,53,2、算术表达式和运算符的优先级与结合性,(1)、算术表达式定义: 用算术运算符号和括号将运算对象(也称操作数)连接起来的、符合C语法规则的式子,称为算术表达式。 其中:运算对象包括常量、变量、函数等。 例如: 3+4.5*a-b*4/3 a*b/c-1.5+a,54,(2)、优先级和结合性,在C语言中规定,对表达式求值时,按运算符的优先级别高低,从高到低进行运算。另外,C语言中还规定了运算符的结合性,算术运算符的结合方向是“从左至右”又称为“左结合性”。 如:a+b*c 不是所有的运算符的结合性都是从左至右,有的是从右至左的,称“右结合性”。 在书中附录c中P365中表明。,55,3、强制类型转换运算符,可以利用强制类型转换运算符将一个表达式转换成所需类型。 例如: (float)x (int)x+y (int)(x+y) (float)(5%3) 其格式为: (类型)(表达式),56,注意:在强制类型转换时,产生的是一个临时数据,这个临时数据的类型是指定的类型,而原始数据的类型不会发生改变。 void main( ) float x; int y; x=3.6; y=(int)x; printf(“%f,%d”,x,y); 运行结果为:3.600000 , 3,57,讲到这里,我们已经知道:在C语言中有两种形式的类型转换(且只有两种),一种是系统自动进行的类型转换,如5*0.6;另一种是强制类型转换,象(int)x%8。 在上面这个例子中%运算符要求两个运算数都为整型,如果有一个运算数不是整型,那么系统将报错。这种情况下,如果变量x不是整型,那么必须使用强制类型转换。,58,4、自增、自减运算符(+、-),+是自增运算符。+k或k+都是让变量k的值加1。 -是自减运算符。-k或k-都是让变量k的值减1。 区别: +K含义:先执行K=K+1,再使用K值。 K+含义:先使用K值后,再执行K=K+1。,59,例如: k=1; k=1; j=+k; j=k+; 左边k先变成2,j=2 右边k为1,j=1然后K为2。 总之,自增、自减运算符都有两种用法: (1)前置运算运算符放在变量之前 如:+变量、变量 先使变量的值增(或减),然后再以变化后的值参与其它运算,即先增减、后运算。 (2)后置运算运算符放在变量之后 如:如变量、变量 变量先参与其它运算,然后再使变量的值增(或减),即先运算、后增减。,60,自增、自减运算符使用中的问题说明,(1)这两种运算符只能用于变量,而不能用于常量或表达式。如:2+或(a+b)+ (2)+、- 运算符的优先级相同,比算术运算符优先级要高。其结合性是 “从右至左”的。-i+ 相当于-(i+)。 i=3; =3; j=-i+; m= +; printf(“%d”,j); 结果是:-3 printf(“%d”,m); 结果是:4,61,例: void main() int x=6, y; printf(“x=%dn“,x);/*输出x的初值*/ y = +x; /*前置运算*/ printf(“x=%d,y=%dn“,x,y); y = x-; /*后置运算*/ printf(“x=%d,y=%dn“,x,y); 运行结果: x=6 x=7,y=7 x=6,y=7,62,5、注意程序的写法,在调用函数是有的系统是自左至右,有的是自右至左。 =3; Printf(“%d,%d”,+); 结果为:3 ,3 (有的系统左至右) 4 ,3(多数系统右至左) 最好写成: =3; j=+; printf(“%d,%d”,j,); 结果为:3,4,63,如果的初值为 (i+)+(i+)+(i+) 有的系统: 有的系统: 为了避免歧义性写成: i=3; a=i+; b=i+; c=i+; d=a+b+c; 任何系统结果都一样。,64,如 i+j C多数是自左到右的处理,所以它理解为(i+)+j,而不是i+(+j)。 最好不要用这种易产生歧义的表达。,65,3.9 赋值运算符和赋值 表达式,66,1、赋值运算符,“=”就是赋值运算符。 格式:变量=表达式 赋值过程中遇到的问题: 如果赋值运算符两侧的变量和表达式的类型都为数值型时,系统自动进行类型转换。怎么转换呢?有一个原则,要尽量保持赋值前后数据的一致性。我们来分别看一下:,67,2、类型转换,(1) 将实数赋给整数时舍去小数点。 如i=3.12 (2) 将整数赋给实数时后面加0。 (3) 将double型数据赋给float变量时,截取前7位有效数字,存到float变量中。 如:float f; double d=123.456789e100; f=d; (4)字符型赋给整数时,如果系统把字符处理为无符号的字符类型,则将字符的8位,放在整数的低8位,高8位补零;如果系统把字符处理为有符号的,若字符的最高位为0,则整数的高8位全为0,若字符的最高位为1,则整数的高8位全为1。这称为“符号扩展”,是为了保证数值不变。 (5)将int , short , long 型数据赋给char 型变量时,只将其低8位原封不动地送到 char中,称为“截断”。 (6)把带符号的整型数据赋给long型时,要符号扩展,把整型的16位放到Long的低16位,如果是正数,高16位补0,如果是负数,高16位补1。以保证数值不变。 (7)把unsigned int型数据赋给long int时,只需把高位补0。 (8)把非unsigned型数据赋给长度相同的unsigned型,只需原样赋值,如果有符号也作为数值一起传送。如例3.9,68,69,70,3、复合的赋值运算符,定义:在赋值运算符之前加上其它运算符。 例如:x+=3相当于x=x+3 x*=(y+z)相当于x=x*(y+z) 所以A+=B解释为:将“A+”移到“=”右侧得到“=A+B”,然后在左侧添上“A”就得到了“A=A+B”。 共有10种复合运算符: +=、-=、*=、/=、%=、=、&=、 =、|= (其中后五种是位运算的运算符,在位运算那章介绍。),71,四、赋值表达式,格式: 赋值表达式的求解过程: 先求赋值运算符右侧的表达式的值

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论