数据的存储

来源:互联网 发布:金山软件管家 编辑:程序博客网 时间:2024/04/27 14:01

现我总结一下数据类型(这里以VC6.0中的int类型为例)在内存中的储存,主要讨论不同进制之间的转换、编码(数据如何转换成电脑中存储的二进制)、数据类型的存储范围。


1:不同进制之间的转换:(D:代表十进制、O:代表八进制、OX:代表十六进制。------用在数字的后面进行标识。)

a:十进制转换成二进制:--------------除2取余,直至商为0,余数倒列排序。

  eg:将125转换成二进制:

         125/2        62--------1

          62/2         31--------0

           31/2      15---------1

         15/2          7-----------1

          7/2           3------------1

         3/2            1-----------1

         1/2           0-----------1

所(125)D =1111101  

b:八进制转换成十进制:

eg:(125)O转化成十进制是:1*8*8+2*8+5=85;

C:十六进制转换成十进制:

eg:(125)OX=1*16*16+2*16+5=293;


d:二进制转换成八进制:---------从右向左,三位一段,不足添0.

eg:(1,111,101) = (001,111,101)=(175)o


e: 二进制转换成十六进制:------从右向左,四位一段,不足位添0;

eg:(1111101)=(0111,1101)=(7D)ox

PS:这个经常用于编码的转换。


f:八进制转成二进制:-----从右往左,一分为三,去掉最高位的0。

eg:(175)o = (001,111,101) =(1111101)


g:十六进制转换成二进制-----从右往左,一分为四,去掉最高位的0.

eg:(7D)ox=(0111,1101)=(1111101)


h:八进制转换成十六制:-------以二进制为桥梁进行转换。

eg:(7D)ox要转换成十六进制:

1:先把(7D)ox转换成二制制为:(7D)ox=(0111,1101)=(1111101)

2:再将二进制转换成八进制:(1,111,101) = (001,111,101)=(175)o

即:(7D)OX=(175)O;


--------------------------------------------------------------以上即是字节的转换是编码转换的基础-----------------------------

Q:整数在内存中的存储是以二进制,负数、正数、零是采用什么的二进制存储的?

A:数据是能过编码(源码、补码、ACSII、unicode、)规则转换成二进制,然后存储在内存中的,不同数据类型以不同的编码方式进行转换,现在对整数通过补码进行转换的情况进行分析。


A:正整数的存储:

     直接将正整数转化成二进制,然后存储在4个字节(32bit)中的内存中,不足之位自动添零。

    如:125转化成二进制是:1111101。则它在内存的存储形式是:

00000000,00000000,00000000,01111101

B:负数的存储:

求出负数对应的正数的二进制数,然后将所有的位进行取反,未尾加1,不足之位加1.(因为负数首位是1开始)

如:-125在内存中的存储是:

先求125的二进制:1111101,对各位进行取反得到:0000010,再对未尾加1得到:0000011.

则它在内存中的存储形式是:1111,1111,1111,1111,1111,1111,1000,0011 即:0xFFFFFF83

可以在VC6.0中对其进行验证:


int main(){      int i = 0xFFFFFF83;            printf("%d\n",i);      return 0;}

输出结果为:-125

C:零的存储形式就是32个零。


那如果知道一个数据在内存中的存储形式,怎样求它的原数呢?

A:如果该数的二进制的首位是以0开始,说它是一个正数,可以直接将二进制数转换成十进制即可。

eg:0000,0000,0000,0000,0000,0000,0111,1101 ------------------125


B:如果该数的二进制的首位是以1开始的,说明它是一个负数,则求的步骤是:

先对该二进制进行取反,再加1,转换成十进制,即是这个负数的绝对值。

设 某数的二进制为:1101011。取反:0010100 ,加1,0010101 转换成十进制为:(001,0101)=(15)ox=21.

所以该数为:-21.

可以在VC++中验证一下:由于它的存储是:1111,1111,1111,1111,1111,1111,1110,1011 即可定义一变量为:

int i = 0xFFFFFFEB

int main(){      int i =0xFFFFFEB;      return 0;}

输出结果是:-21.


一个数据类型的取值范围(以一个字节的char类型为例):char类型占一个字节,所以它在内存中的存储形式有:

0000,0000          0

0000,0001 1

0000,0010 2

0000,0011

......................

0111,1111------------------------(这个就是最大的整数的二进制)(7F)ox=127;

1000,0000-------------------   最大负数--------------   -128

1000,0001 -127

1000,0010

....................

1111,1111-----------------    -1

所以一个32字节的int数据类型的最大值为:0x7FFFFFFF. 即:2的32次方减1

最小值为:0x80000000   即:2的32次方的相反数。


一个关于数据截取的问题:

如:char ch = 129;

求 char 的输出值:

由于129是一个整形,所以在内存中是占四个字节,而char在内存中是占一个字节,所以前三个字节被截断。

即:(0000,0000,0000,0000,0000,0000)1000,0001 只有后面的八bit会赋值给ch所占的内存单元。

那 就转换为己知内存中的二进制求原数。一:取反。二:加一:三:取相反数。

取反:0111,1110,加1:0111,1111.   (0111,1111)=(7F)0x=127

所以输出结果为:-127