本文主要分析int,float,double,char的表示原理和范围,以及与计算机系统位数等的关系
位(bit)、字节(byte)、字(word)
最小的存储单元是位(bit),可以储存 0 或 1;
字节(byte)是常用的计算机存储单位。对于几乎所有的机器,1 字节均为 8 位。这是字节的标准定义,至少在衡量存储单位时是这样(但是,C 语言对此有不同的定义)。既然
1 位可以表示 0 或 1,那么 8 位字节就有 256(2 的 8 次方)种可能的 0、1 的组合。通过二进制编码(用 0 和 1 便可表示数字),便可表示 0~255 的整数或一组字符;
字(word)是设计计算机时给定的自然存储单位。对于 8 位的微型计算机(如,最初的苹果机),1 个字长只有 8 位。从那以后,个人计算机字长增至 16 位、32 位,直到目前的 64 位。计算机的字长越大,其数据转移越快,允许的内存访问也更多。
总的来说,C语言的数据类型可以分为整数类型和浮点数类型:int表示基本的整数类型,char也可以表示较小的整数;float,double表示带小数点的数。
浮点数和整数
对于我们来说,整数和浮点数的区别是它们的书写方式不同。对计算机而言,它们的区别是储存方式不同。
1.整数
计算机以二进制数字存储整数
2.浮点数
在一个值后面加上一个小数点,该值就变成了浮点值。故7为整数,而7.00是浮点数。浮点数的储存方式可以由下图来理解:
因为在任何区间内(如,1.0 到 2.0 之间)都存在无穷多个实数,所以计算机的浮点数不能表示区间内所有的值。浮点数通常只是实际值的近似值。例如,7.0 可能被储存为浮点值 6.99999。由此可以得到,在一些算术运算时,浮点数损失的精度也会更多。
———————————————————————————————————————
进入正题
int类型
int 类型是有符号整型,即 int 类型的值必须是整数,可以是正整数、负整数或零。其取值范围依计算机系统而异。一般而言,储存一个 int 要占用一个机器字长。因此,早期的 16 位 IBM PC 兼容机使用16 位来储存一个 int 值,其取值范围(即 int 值的取值范围)是-32768~32767(-2^31 ~ 2^31-1,0 代表 +0,-0 代表 -2^31,故负数比整数多一个)。目前的个人计算机一般是 32 位,因此用 32 位储存一个 int 值。现在,个人计算机产业正逐步向着 64 位处理器发展,自然能储存更大的整数。ISO C 规定 int 的取值范围最小为-32768~32767。一般而言,系统用一个特殊位的值表示有符号整数的正负号。
char类型
char 类型用于储存字符(如,字母或标点符号),但是从技术层面看,char 是整数类型。因为 char类型实际上储存的是整数而不是字符。计算机使用数字编码来处理字符,即用特定的整数表示特定的字符。
通常我们用的都是ASCII编码,标准ASCII编码范围是0~127,只需要7位二进制数即可表示。而char类型一般被定义为8位存储单元,故容纳标准ASCII码绰绰有余。一些其他的系统会提供拓展ASCII码,但是也在八位表示范围之内。
C语言把一字节定义为char类型占用的位(bit)数,因此无论是16位还是32位系统,都可以使用char类型。
用例子来理解char的原理:
char grade = 65; /*意思应当是把A赋值于grade,但这不是好的编程风格,因为需要系统能使用ASCII码*/
char grade = 'A'; /*这样不会在任何系统中出现问题*/
char grade = 'B'; /* 假设在int为32位,char为8位的ASCII系统中,有此代码*/
对于第三行代码,‘B’本来是对应数值66存储在32位存储单元,现在却可以存储在8位的存储单元grade中。
利用字符常量这种特性,可以定义一个字符常量‘FATE’,把4 个独立的 8 位 ASCII 码储存在一个 32 位存储单元中。如果把这样的字符常量赋给 char 类型变量 grade,只有最后 8 位有效。因此,grade 的值是’E’。
根据 C90 标准,C 语言允许在关键字 char 前面使用 signed 或 unsigned。这样,无论编译器默认char 是什么类型,signed char 表示有符号类型,而 unsigned char 表示无符号类型。这在用 char类型处理小整数时很有用。如果只用 char 处理字符,那么 char 前面无需使用任何修饰符。
float类型
C 标准规定,float 类型必须至少能表示 6 位有效数字,且取值范围至少是 10-37~10+37。前一项规定指 float 类型必须至少精确表示小数点后的 6 位有效数字,如 33.333333。后一项规定用于方便地表示诸如太阳质量(2.0e30 千克)、一个质子的电荷量(1.6e-19 库仑)或国家债务之类的数字。通常,系统储存一个浮点数要占用 32 位。其中 8 位用于表示指数的值和符号,剩下 24 位用于表示非指数部分(也叫作尾数或有效数)及其符号。
double类型
double 类型和 float 类型的最小取值范围相同,但至少必须能表示 10 位有效数字。一般情况下,double 占用 64 位而不是 32 位。一些系统将多出的 32 位全部用来表示非指数部分,这不仅增加了有效数字的位数(即提高了精度),而且还减少了舍入误差。另一些系统把其中的一些位分配给指数部分,以容纳更大的指数,从而增加了可表示数的范围。无论哪种方法,double 类型的值至少有 13 位有效数字,超过了标准的最低位数规定。
不同编译器下数据类型长度
此处可以自己利用电脑进行查找
#include<stdio.h>
int main()
{int a,b;
char c,d;
printf("Type int has a size of %d bytes.\n", sizeof(int));
printf("Type char has a size of %d bytes.\n", sizeof(char));
printf("Type long has a size of %d bytes.\n", sizeof(long));
printf("Type double has a size of %d bytes.\n",sizeof(double));
getchar();
return 0;
}
结果为:
Type int has a size of 4 bytes.
Type char has a size of 1 bytes.
Type long has a size of 4 bytes.
Type double has a size of 8 bytes.
32位编译器:(Visual Studio C++)
sizeof(char) = 1
sizeof(short) = 2
sizeof(float) = 4
sizeof(double) = 8
sizeof(int) = 4
sizeof(long) = 4
sizeof(long long) = 8
sizeof(void *) = 4 (表示指针类型数据长度)
64位编译器:
sizeof(char) = 1
sizeof(short) = 2
sizeof(float) = 4
sizeof(double) = 8
sizeof(int) = 4
sizeof(long) = 8
sizeof(long long) = 8
sizeof(void *) = 8
16位编译器:(Turbo C/Turbo C++)
sizeof(char) = 1
sizeof(short) = 2
sizeof(float) = 4
sizeof(double) = 8
sizeof(int) = 2
sizeof(long) = 4
sizeof(long double) = 16
sizeof(void *) = 4