在计算机编程语言的学习中,很多初学者甚至好几年的老手对基本类型的应用和理解都存在着一些模糊的地方,今天我就拿C语言和Java语言中的基本类型来举例,深度解剖它们的设计原理。
一、计算机存储处理信息的单位
1bit(位): 表示一个二进制数码0或1,是计算机存储处理信息的最基本的单位(存储单元)。这里的bit和电信号之间通过高(1),低(0)电平进行对应处理,让硬件做出相应的操作。
byte(字节):一个字节由8个位组成 。它表示作为一个完整处理单位的8个二进制数码。现目前计算机上多使用《美国国家信息交换标准代码》——ASCII编码(由美国国家标准委员会制定),如:字符“A”的二进制编码是“0100 0001”即41H或65D “#”的二进制编码是“0010 0011”即23H或35D,一个汉字是两个字节,一个英文字母是一个字节,标点符号也是一个字节。
注意:因为byte是一个完整处理单位(这个一个规定设计),所以编程语言中数据类型的长度基本单位为字节。字(Word):16个位为一个字(即两个字节是一个字) ,它代表计算机处理指令或数据的二进制数位数,是计算机进行数据存储和数据处理的运算单位。通常称16位是一个字,32位是一个双字,64位是两个双字。
注意:
1、bit的设计是根据二进制0,1设计,电信号和数字通信间通过高低电平进行通信,而高低匹配二进制的1,0。
2、一个存储单元(一个byte)都有一个地址,是一个整数编码,可以表示为二进制整数。编程语言中的变量和主存储器的存储单元相对应。变量的名字对应着存储单元的地址,变量内容对应着单元所存储的数据。(C语言中的指针,地址,值)
3、一个byte的完整处理单元(存储/读取/解析),是CPU与存储器间的地址总线和数据总线宽度设计的基本单元,个别芯片会出现地址总线20位,大部分都是一个byte的倍数,因为冯诺依曼结构是顺序执行指令。
二、计算机中的字长,寻址空间,字符的概念
字长:是CPU的主要技术指标之一,指的是CPU一次能并行处理的二进制的位数,字长是8的整倍数,通常的PC机的字长为16位,32位,64位。一台16位字长的PC机可以直接处理216(65536)之内的数字,对于超过此范围的数字需要分解的方法来处理。32位机比16位机优越的原因之一就在于它在一次操作中能处理的数字大,32位机字长的PC机能直接处理的数字为232(40亿),能处理的数字越大,则操作的次数就越少,从而系统的效率就越高。
寻址空间:要看处理器的地址总线的位数,而不是它的字长。如Intel P4处理器字长为32位,地址总线也是32位。8086的数据总线为16为,地址总线为20位(则可寻址的内存空间为220=1MB)。新兴的64位处理器的数据总线为64位,地址总线大部分是32位。再看地址总线与寻址范围的关系,存储单元是以Byte为单位,N根地址总线能够访问2N个存储单元,于是有32位地址总线可访问2^32个存储单元,即4GB。
字符:是可使用多种不同字符方案或代码页来表示的抽象实体。例如,Unicode UTF-16 编码将字符表示为 16 位整数序列,而 Unicode UTF-8 编码则将相同的字符表示为 8 位字节序列。公共语言运行库使用 Unicode UTF-16(Unicode 转换格式,16 位编码形式)表示字符。
注意:
1、字长取决于它的通用寄存器、内存储器、ALU的位数和数据总线的宽度。字长=2^数据总线位数
2、寻址空间就是CPU一次性能够寻找多大内存,然后再从这些内存地址中找到匹配的地址。寻址空间=2^地址总线
3、字符是字符方案的实体,字符方案(字符编码)是人类语言和计算机二进制编码间的协议方案。
三、C与Java基本数据类型设计
编程语言如果需要做和人类直接沟通,那么需要对我们认知的数字和字符进行定义,所以编程语言的基本数据类型也分为字符和数字
注意:
1、不同编译系统,整数的存储长度不同。对于16位的编译系统,int为2字节;而对于32位的编译系统,int为4字节。可以用sizeof运算符测试。
2.、而且在C/C++中可以通过类型修饰符signed和unsigned用于修饰字符型和整型。
3.、对于C/C++语言long是32bit是历史的包袱, long long是8字节
四、对于float和double的取值范围和精度
首先我们了解下它们的内存结构,如下图所示:
- 1、范围
float和double的范围是由指数的位数来决定的
float取值范围 2^(-2^7~+2^7-1)
double取值范围 2^(-2^10~+2^10-1)
- 2、精度
float和double的精度是由尾数的位数来决定的。浮点数在内存中是按科学计数法来存储的,其整数部分始终是一个隐含着的“1”,由于它是不变的,故不能对精度造成影响。
float的精度2^23=8388608 7位有效数字
double的精度2^52=4503599627370496 15位有效数字
注意
1、因为浮点数精度左边还有一个隐含着的1所以 float 7-8位有效数字 double 15-16位有效数字。
针对enum,bool,boolean,指针等类型这里不再讨论