八种数据类型数据类型有哪11种

6.1 数据类型

前一章介绍了分支、循环、函数的几个基本结构。 本章主要介绍数据类型和公式。 本节介绍数据类型的概念和一些简单的数据类型的存储形式,以及可能值的范围和精度,通过实例解读整数的“反向卷”特性,分析浮点的“不准确的表示”特性。

编程的目的是解决现实问题,编程处理的对象是数据。 因此,数据的收集、表达、保存是编程前必须解决的问题。 数据是观察和测量的结果,有些用年、月、日等整数表示,但大部分用实数表示。 数据有定量描述和定性描述两种,测量结果用数值定量描述,有的观察结果只能定性描述。 例如,记述某人的“wldyx、客观、幽默”等。 这些数据分别被称为数值型和非数值型数据。

无论如何,由于收集的数据在计算机内部都用二进制表示,因此要存储收集的数值型数据和数值型以外的数据,必须预先进行——编码,或者以某种形式存储在计算机内部数据类型是对不同类型数据的抽象,反映了数据编码格式、存储长度和可以参与的运算。 c语言中预先准备了字符型、整数型、long型、单精度浮点型、双精度浮点型5种简单型。 程序员也可以按一定的方式任意组合这些类型,以构建自己需要的类型——自定义类型。

实际上,c语言的所有简单类型都是数值类型。 因为字符类型数据被认为是8位最短整数类型。 因此,整数分为4种类型: 8位整数字符、16位整数短整型或短整型、32位整数长整型或整型、64位整数长整型。 我介绍了整数型已经以补数存储,目的是将减法变为加法。 正数的补数与原始代码相同。 原码是指将整数直接转换后的二进制数,反码是指除了原码的代码位以外,每二进制位通过反运算——0将1或1改变为0,然后将反码加1得到补数。 例如,短整数型65的原码、反码和补码都是二进制0000001000001,但短整数型-65的原码为10000001001000001,反码为11111111111 从右向左计数,每四个二进制数对应十六进制位。 因此,与-65对应的十六进制补数为0xffbf。 其中,0x表示十六进制前缀。

整数分为带符号整数和无符号整数,分别用signed和unsigned表示。 如果整数是带符号的数字,则与整数相对应的二进制数的最高最左边)位用于表示符号,1表示负数,0表示正数。 因此,n位二进制整数的可取范围为到,如果有符号字符类型数据的可取范围为-128到127,则有符号短整数的可取范围在-32768到32767之间。 整数为无符号数时,所有位都用于表示数值,取0~的值。 例如,无符号字符的值介于0到255之间,而无符号短整数的值介于65535之间。

c语言中的实数用浮点型表示,分为单精度浮点型float、双精度浮点型double、长倍精度浮点型long double三种,分别占用4字节、8字节、10字节的存储空间长度因编译而异)。 浮点型数据不区分有符号的数和无符号的数,根据IEEE 754标准,以符号位、指数部分、尾数部分三部分保存数据。 浮点数的符号位都只占1位。 float型数据的指数部分为8比特,尾数部分为23比特; double型数据的指数部分为11比特,尾数部分为52比特。 因此,float数据的可取范围为和之间,而double型数据的可取范围为和之间。 浮点型数据的精度为7位,双精度型数据的精度为16位。

明确整数的取值范围和浮点数的精度对编程来说非常重要。 例如,以下程序。

# #包括stdio.h

int主) )

{

短整型a=32767;

a=a 1;

打印机’ % d ‘,a );

返回0;

}开车后会怎么样呢? 当然我认为32768后的结果是32768,显示的是-32768。 为什么呢? 这是因为短的整数数据只有16位。 与32767相对应的二进制是0111111111111,加上1等于1000000000000。 最高位成了1,即这个数成了负数,这个数是多少?

让我们先来看看-32767的原码、反码和补码:

原始代码是11111111111111111111

反向代码为1000000000000000

补数是1000000000000001。 让我们再来看看-1的原码、反码和补数。

原始代码是1000000000000001

反码为1111111111111111110

补数为1111111111111111,所以

-32768==

==

==

==

==

==

也就是说,对应的数为-32768,对应的无符号整数为32768。 也就是说,无符号整数32768有符号整数-32768是相同的个数。

上述情况称为整数“逆卷”。 这是由计算机中规定的整数位数,例如短整数为16位决定的。 当然,如果从-32768再减去1,结果也会“倒带”到最大值32767。 请用手计算一下。

因为是“倒带”,所以以下程序的循环会成为死循环吗?

# #包括stdio.h

int主) )

{

短整型a=1;

wileA0) {

printf%dn ),a );

a=a

+1;
}
return 0;
}

程序中,a的初值为1,然后每执行一次循环a的值就加1。看起来a是一直是大于0的数,但是事实是当a=32767并输出后,a再加1变成了-32768,此时循环条件不满足,循环就束了。

除了“反卷”外,整数的取值范围也是要注意的问题,如想保存n!。短整型最多可以保存7!,短整型计算8!显示结果是一个负数。我们可以改用长整型long保存阶乘,但能保存的最大阶乘只是16!。还可以用long long来保存阶乘,此时可以保存的最大阶乘也只是20!。如果要保存更大的阶乘,可以使用双精度浮点型double来保存。

浮点数的取值范围虽然很大,但是精度却是有限的。如以下程序说明float与double的精度情况:

#include <stdio.h>
int main )
{
float a;
double b;
a=123456789;
b=123456789012345678;
printf”a=%.0f,b=%.0lf\n”,a,b);
return 0;
}

程序的输出结果是:

a=123456792,b=123456789012345680

可以看到a的值只有前7位是正确的,第8位进行四舍五入,第9位是一个拉圾数据;b的值前16位是正确的,第17位进行四舍五入,第18位是一个拉圾数据。可见,浮点数表示数的范围虽然很大,但是精度并不高。

浮点数还有一个致命的弱点,即不能精确表示小数,即使保存0.1也是有误差的。我们来猜一下以下程序段显示什么?

#include <stdio.h>
int main )
{
float b;
b=0.1;
ifb==0.1)
printf”b==0.1″);
else
printf”b!=0.1″);
return 0;
}

根据我们的经验,b是0.1,所以if语句的条件表达式b==0.1为真,所以应该显示“b==0.1”。但是运行结果却与我们预想的不同,显示的是“b!=0”.1。为什么呢?看以下程序:

#include <stdio.h>
int main )
{
float b;
b=0.1;
printf”%.10f\n”,b);
printf”%.10f\n”,0.1);
return 0;
}

程序执行后显示结果为:

0.1000000015
0.1000000000

原来常量0.1是双精度浮点数,b是单精度浮点数。在比较时b要转换成双精度浮点数,因此才有b与0.1不等的情况。所以浮点数的比较可采用两个浮点数相减的绝对值与某个很小的正小数比较,如果小于可以认为两者相等。如:

fabsb – 0.1)<1e-6

可以用来表示b与0.1是否相等。

本节介绍了数据类型的概念及几种简单类型的存储格式,讲解了整数的“反卷”特性及浮点数的相等比较操作。这些都会对正确理解和编写程序起到非常重要的作用。本节就讲到这里,下次再见!

Published by

风君子

独自遨游何稽首 揭天掀地慰生平

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注