1、第3章 数据的种类数据类型,计算机如何识数数制 整型字符型 浮点型 类型转换 综合应用类型转换跟我上机,第3章 数据的种类数据类型,计算机如何识数数制 整型字符型 浮点型 类型转换 综合应用类型转换跟我上机,第3章 数据的种类数据类型,计算机如何识数数制 整型字符型 浮点型 类型转换 综合应用类型转换跟我上机,第3章 数据的种类数据类型,计算机如何识数数制 整型字符型 浮点型 类型转换 综合应用类型转换跟我上机,第3章 数据的种类数据类型,计算机如何识数数制 整型字符型 浮点型 类型转换 综合应用类型转换跟我上机,第3章 数据的种类数据类型,计算机如何识数数制 整型字符型 浮点型 类型转换 综
2、合应用类型转换跟我上机,第3章 数据的种类数据类型,计算机如何识数数制 整型字符型 浮点型 类型转换 综合应用类型转换跟我上机,第3章 数据的种类数据类型,计算机如何识数数制 整型字符型 浮点型 类型转换 综合应用类型转换跟我上机,3.1 计算机如何识数数制,3.1.1 二进制 3.1.2 八进制 3.1.3 十六进制 3.1.4 数制间的转换,3.1 计算机如何识数数制,数据在计算机里是以二进制形式的数表示的,在实际程序中,许多系统程序需要直接对二进制位的数据操作,还有不少硬件设备与计算机通信都是通过一组二进制数控制和反映硬件的状态。在表示一个数时,二进制形式位数多,八进制和十六进制比二进制
3、书写方便些,他们都是计算机中计算常用的数制。,3.1.1 二进制,二进制是逢二进一的数制,目前的计算机全部都是采用二进制系统。0和1是二进制数字符号,运算规则简单,操作方便,因为每一位数都可以用任何具有两个稳定状态的元件表示,所以二进制易于用电子方式实现。,3.1.1 二进制,1. 二进制运算规则 加法:000,011,101,1110 减法:000,101,110,1011 乘法:000,010,100,111 除法:010,111例如,((1100))2 + ((0111))2计算如下:1100 + 011110011,3.1.1 二进制,2. 二进制转换为十进制 十进制是逢十进一,由数字
4、符号0,1,2,3,4,5,6,7,8,9组成,可以这样分析十进制数: (1234)10 = 1 * 103 + 2 * 102 + 3 * 101 + 4 * 100 = 1000 + 200 +30 + 4 =(1234)10 采用同样的方式转换二进制到十进制。 (1101)2 = 1 * 23 + 1 * 22 + 0 * 21 + 1 * 20 = 8 + 4 + 0 + 1 = (13)10 (10.01)2 = 1 * 21 + 0 * 20 + 0 * 2-1 + 1 * 2-2 = 2 + 0 + 0 + 0.25 = (2.25)10,3.1.1 二进制,3. 十进制转换二进
5、制 十进制整数转换为二进制:方法是除以2取余,逆序排列,以(89)10为例,如下。 89 2 余1 44 2 余0 22 2 余0 11 2 余1 5 2 余1 2 2 余0 1 余1 (89)10 = (1011001)2 (5)10 = (101)2 (2)10 = (10)2,3.1.1 二进制, 十进制小数的转换为二进制:方法是乘以2取整,顺序排列,以(0.625)10为例,如下。 0.625 * 2 = 1.25 取整1 0.25 * 2 = 0.5 取整0 0.5 * 2 = 1 取整1 (0.625)10 = (0.101)2 (0.25)10 = (0.01)2 (0.5)10
6、 = (0.1)2,3.1.2 八进制,八进制是逢八进一的数制,采用07八个数字组成。八进制比二进制书写方便,也常用于计算机计算。需要注意的是,C语言中,八进制数以数字0开头,比如04,017等等。 1. 八进制转换为十进制和二进制转换为十进制的原理相同,如:(64)8 = 6 * 81 + 4 * 80 = 48 + 4 =(52)10 2. 二进制转换为八进制整数部份从最低有效位开始,以3位二进制数一组,最高有效位不足3位时以0补齐,每一组均可转换成一个八进制的值,转换结果就是八进制的整数。小数部份从最高有效位开始,以3位一组,最低有效位不足3位时以0补齐,每一组均可转换成一个八进制的值,
7、转换结果就是八进制的小数。例如:(11001111.01111)2 = (011 001 111.011 110)2 = (317.36)8,3.1.3 十六进制,十六进制就是逢十六进一的数制,采用09和AF十六个数字组成(A代表10,F代表15),也常用于计算机计算。C语言中,十六进制数以数字0x开头,比如0x1A,0xFF等。 1. 十六进制转换为十进制 和二进制转换为十进制的原理相同,如: (2FA)16 = 2 * 162 + F * 161 + A * 160= 512 + 240 + 10 =(762)10 2. 二进制转换为十六进制 与二进制转换为八进制相似,只是转换为十六进制时
8、,以4位二进制数为一组,每一组转换为一个十六进制的值。例如: (11001111.01111)2 = (1100 1111.0111 1000)2 = (CF.78)16,3.1.4 数制间的转换,前面已经接触过标准输出函数printf()了,这里就使用printf()函数输出转换的结果。printf()函数的格式控制参数如下表所示。,3.1.4 数制间的转换,【范例3-1】 分别使用十进制、八进制和十六进制输出已知数值。01 #include 02 int main(void) 03 04 unsigned int x=12; 05 unsigned int y=012; /*八进制0开头*
9、/ 06 unsigned int z=0x12; /*十六进制0x开头*/ 07 printf(“十进制%u转化为 八进制%o 十六进制%xn“,x,x,x); /*%u表示无符号十进制数*/ 08 printf(“八进制%o转化为 十进制%u 十六进制%xn“,y,y,y); /*%o表示无符号八进制数*/ 09 printf(“十六进制%x转化为 八进制%o 十进制%un“,z,z,z); /*%x表示无符号十六进制数*/ 10 return 0; 11 ,3.2 整型,整型数据,英文单词是Integer,比如0,-12,255,1,32767等等这些都是整型数据。整型数据中是不允许出现
10、小数点和其它特殊符号的。 整型数据共分为七类,分别是字符型、短整型、整型、长整型、无符号短整型、无符号整型和无符号长整型。其中短整型、整型和长整型是有符号数据类型。,3.2 整型,3.2 整型,1. 取值范围,3.2 整型,2. 有符号数和无符号数 对于有符号数,以最高位(左边第一位)作为符号位,最高位是0表示的数据是正数,最高位是1表示的数据是负数。,3.2 整型,对于无符号整数,因为表述的都是非负数,一个字节中的8位全部用来存储数据,不再设置符号位。,3.2 整型,3. 类型间转换不同类型的整型数据所占的字节数不同,他们在相互转换时需要格外留心,不要把过大的数据放在过小的数据类型中,在把占
11、字节较大的数据赋值给占字节较小的数据时,防止出现以下的情况。例如int a = 2147483648;printf(“%d“,a);这样赋值后,输出变量a的值并非预期的2147483648,而是-2147483648,原因是2147483648超出了int类型能够装载最大值,数据产生了溢出。如果换一种输出格式控制符,代码如下所示:printf(“%u“,a);输出的结果就是变量a的值,原因是%u是按照无符号整型输出的数据,而无符号整型的数据范围上限大于2147483648这个值。,3.2 整型,unsigned short a = 256;char b = a;printf(“%d“,b);这
12、样赋值后,输出变量b的值并非预期的256,而是0,原因是256超出了char类型能够装载最大值,b只截取了a的低8位的数据,如下:,变量a,变量b,3.2 整型,当把占字节较小的数据赋值给占字节较大的数据时,可能出现以下两种情况。 第1种情况,当字节较大数是无符号数时,转换时新扩充的位被填充成0 char b = 10; unsigned short a = b; printf(“%u“,a); 这样赋值后,变量a中输出的值是10,原因如下:,变量b,变量a,3.2 整型,第2种情况,当字节较大数是有符号数时,转换时新扩充的位被填充成符号位char b = 255;short a = b;pr
13、intf(“%d“,a);这样赋值后,变量a输出的值是-1,变量a扩充的高8位,根据变量b的最高位1都被填充成了1,所以数值由正数变成了负数,因为变量a的最高位符号位是1,至于为什么16个1表示的是-1,涉及到二进制数的原码和补码问题,这里先不深究。转换图示如下:,变量b,变量a,3.3 字符型,字符型是整型数据中的一种,它存储的是单个的字符,存储方式是按照ASCII码(American Standard Code for Information Interchange,美国信息交换标准码)的编码方式,每个字符占一个字节,8位(ASCII码可查阅王牌2中的相关内容)。 使用单引号“”把字符引起
14、来,用以和变量、其他数据类型区别。比如:A,5,m,$,;等等。,3.3 字符型,比如有这样5个字符:H、e、l、l、o,他们在内存中存储的形式如下的图表所示。,3.3 字符型,字符型的输出,既可以使用字符的形式输出字符,即采用“%c”格式控制符,还可以使用上小一节采用的其他整数输出方式。比如: char c = A; printf(“%c,%u”,c,c); 输出结果是:A,65 此处65是字符A的ASCII码。,3.3 字符型,【范例3-2】 字符和整数的相互转换输出01 #include 02 int main(void) 03 04 char c=a; /*字符变量c初始化*/ 05
15、unsigned i=97; /*无符号变量i初始化*/ 06 printf(“%c,%un“,c,c); /*以字符和整形输出c*/ 07 printf(“%c,%un“,i,i); /*以字符和整形输出c*/ 08 return 0; 09 ,3.3 字符型,字符的家族中,控制符是无法通过正常的字符形式表示,比如常用的回车、换行、退格等等,需要使用特殊的字符形式来表示他们,这种特殊字符称为转义符。,3.3 字符型,3.3 字符型,【范例3-3】 输出字符串,分析转义符的作用。01 #include 02 int main(void) 03 04 printf(“12345678901234
16、567890n“); /*参考数据*/ 05 printf(“abctdefn“); /*转移符使用*/ 06 printf(“abctdebfn“); 07 printf(“abctdebrfn“); 08 printf(“abc“def“ghi?n“); 09 printf(“整数98n“); /*转移符数制*/ 10 printf(“八进制表达整数98是 142n“); 11 printf(“十六进制表达整数98是x62n“); 12 return 0; 13 ,3.4 浮点型,C语言中除了整型外,另外一种数据类型就是浮点型,浮点型可以表示有小数部分的数据。浮点型包含三种数据类型,分别是
17、单精度的float类型,双精度的double类型,和长双精度long double类型。,3.4 浮点型,3.4 浮点型,参与运算的表达式中存在double类型,或者说,参与运算的表达式不是完全由整型组成的,在没有明确的类型转换标识的情况下(将在下一小节中讲解),表达式的数据类型就是double类型。例如: 1 + 1.5 + 1.23456789 /*表达式运算结果是double类型*/ 1 + 1.5 /*表达式运算结果是double类型*/ 1 + 2.0 /*表达式运算结果是double类型*/ 1 + 2 /*表达式运算结果是int类型*/例子当的1.5,编译器默认它为双精度的dou
18、ble类型,精度高占据存储空间大,如果只希望以单精度float类型运行,可以在常量后添加字符f或者F都可以,比如1.5F,2.38F。同样的,如果希望数据是以精度更高的long double参与运算,可以在常量后添加字符l或者L都可以,比如1.51245L,2.38000L。建议使用大写L,因为小写l容易和数字1混淆。,3.4 浮点型,再举几个运算的表达式的例子,如下所示: int i,j; float m; double x; i + j /*表达式运算结果是int类型*/ i + m /*表达式运算结果是float类型*/ i + m +x /*表达式运算结果是double类型*/,3.4
19、 浮点型,指数形式如下所示(e或者E都可以) 2.0e3 表示2000.0 1.23e-2 表示0.0123 .123e2 表示12.3 1e-3 表示0.001 对于指数形式,有以下两点要求: 字母e前面必须要有数字 字母e的后面必须是整数,3.5 类型转换,3.5.1 隐式转换 3.5.2 显式转换,3.5 类型转换,计算过程中,如果遇到不同的数据类型参与运算该怎么办,是终止程序还是转换类型后继续运算。编译器采取第二种方式,如果能够转换成功,程序继续运算,如果转换失败,程序报错同时终止运行。数据类型有两种转换方式,分别隐式转换和显式转换。,3.5.1 隐式转换,C语言中设定了不同数据参与运
20、算时的转换规则,编译器会在悄无声息中进行数据类型的转换,进而计算出最终结果,这就是隐式转换。,3.5.1 隐式转换,int i;i = 2 + A;先计算“=”号右边的表达式,字符型和整型混合运算,按照数据类型转换先后顺序,把字符型转换为int类型65,然后求和得67,最后把67赋值给变量i。double d;d = 2 + A + 1.5F;先计算“=”号右边的表达式,字符型、整型和单精度float类型混合运算,因为有浮点型参与运算,“=”右边表达式的结果一定是double类型,按照数据类型转换顺序,把字符型转换为类型65.0,2转换为2.0,1.5F转换为1.5,最后把双精度浮点数68.5
21、赋值给变量d。,3.5.1 隐式转换,上述情况都是有低精度类型向高精度类型的转换,如果逆向转换,可能会出现丢失数据的危险,编译器会以警告的形式给出提示。例如:int i;i = 1.2;浮点数1.2舍弃小数位后,把整数部分1赋值给变量i。如果i=1.9,运算后变量i的值依然是1,而不是2。 注 意:把浮点数转换为整数,直接舍弃小数位。,3.5.1 隐式转换,【范例3-4】 整型和浮点型数据类型间的隐式类型转换。01 #include 02 int main(void) 03 04 int i; 05 i=1+2.0*3+1.234+c-A; /*混合运算*/ 06 printf(“%dn“,i
22、); /*输出i*/ 07 return 0; 08 ,3.5.2 显式转换,隐式类型转换编译器是会产生警告的,提示程序存在潜在的隐患。如果非常明确的希望转换数据类型,这就需要用到显式类型转换了。 显式转换格式如下所示: (类型名称) 变量或者常量 或者 (类型名称) (表达式),3.5.2 显式转换,例如,需要把一浮点数,以整数的形式使用printf()函数输出,怎么办?就可以调用显示类型转换。float f=1.23;printf(“%dn“,(int)f);可以得到输出结果1,没有因为调用的printf()函数格式控制列表和输出列表前后类型不统一导致程序报错。继续分析上例,显示类型转换只
23、是把f小数位直接舍弃,输出了整数部分,变量f的值和数据类型都没有改变,依然是float类型1.23,可以再次输出结果进行查看。printf(“%fn“, f);输出结果是:1.230000,3.5.2 显式转换,再看下面的例子,分析结果是否相同。例如float f1,f2;f1=(int)1.2+3.4;f2=(int)(1.2+3.4);printf(“f1=%f,f2=%f“,f1,f2);输出结果:f1=4.4,f2=4.0显然结果是不同的,原因是f1只对1.2取整,相当于f1=1+3.4,而f2是对1.2和3.4的和4.6取整,相当于f2=(int)4.6。,3.6 综合应用类型转换,
24、【范例3-5】 综合应用数据类型和类型转换的。01 #include 02 #include 03 int main(void) 04 05 int i; 06 double d; 07 char c=a; 08 printf(“不同进制数据输出字符an“); 09 printf(“%u,0%o,0x%xn“,c,c,c); /*十进制八进制十六进制*/ 10 i=2; 11 d=2+c+0.5F; /*隐式类型转换*/ 12 printf(“隐式数据类型转换%fn“,d); 13 i=d; /*隐式类型转换,舍弃小数位*/ 14 printf(“隐式数据类型转换%dn“,i); 15 d=(int)1.2+3.9; /*显式类型转换,1.2取整*/ 16 printf(“显式数据类型转换%fn“,d); 17 d=(int)(1.2+3.9); /*显式类型转换,和取整*/ 18 printf(“显式数据类型转换%fn“,d); 19 return 0; 20 ,3.8 跟我上机,1 编写C程序,实现以下功能:有一个字符K 以十进制,八进制和十六进制输出对应整数; 利用变换的整数,以转义符形式再输出字符K。,3.8 跟我上机,2 编写C程序,输出下列内容: abc 123? “def” 456n,