数学上的数字,是没有限制的,可以无限大,而在计算机中,受硬件的制约,数据是有长度的(即每个数据最多可以有几个二进制位),称为数据宽度,超过最大宽度的数据将会丢失一部分。我们知道计算机数据表示只能有0,1两个数字,称为二进制,那么在程序编程语言中,我们一般划分数据宽度为三种:

BYTE 字节 8 bit

WORD 16bit  =2字节

DWORD 双字 32bit 双字=2=4字节

C语言为例,char 数据宽度为byteshort 数据宽度为wordint数据宽度为dword

我们分析一下在计算机中数据宽度是如何理解的。

下面我们逐一分析

4位宽度为例,假设计算机只能存储4个二进制位。2^4=16,可以存储16个数字,

0000 0001  0010  0011  0100  0101  0110  0111  1000  1001  1010  1011  1100


1101  1110  1111


若这16个数

全是无符号数:

0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F

全是有符号数:

正数: 0   1   2   3   4   5   6   7

负数: -1   -2   -3   -4   -5   -6   -7   -8

                   F   E    D   C    B   A   9     8

Android4字节对齐和4k对齐 四字节宽度_Android4字节对齐和4k对齐

由上面分析,我们可以看出,计算机中存储的只是若干位的二进制数,计算机并不区分正负数,正负数是编程人员规定的。从示意图可以看出,F为最大负数,因为F再进一位就为0,所以F 是最大的负数,而且从有符号数说起,纵轴左边是负数,最高位为符号位,最高位为1就是负数,为0就是正数。这也可以理解计算机中存储负数,即存储该数绝对值的补码,然后最高位变为1 ,即可。

 

切记,计算机并不决定数是正数还是负数,正负性是由编程人员决定的,从原理上看,无论整数还是负数,在计算机中表示的二进制字符串都相同,由编程人员来确定正负。

比如 8位的二进制数 10000000,若为无符号数,则是128,若是有符号数,则是-128,由此可见,正负性是由编程人员决定的。


同理以8位宽度为例,即以字节byte为例,可以得到示意图,4位二进制用16进制表示

 

无符号数:

0   1   2   3   … FF(10进制为255)

有符号数:

正数: 0   1   2   … 7F(10进制127)

负数: -1    -2   -3 …  -128

FF   FE   FD  …   80

 

Android4字节对齐和4k对齐 四字节宽度_数据_02

 

 

 

 

 

 

 

 

同理 16位宽度,假设计算机只能存储16位二进制位

无符号数:

0   1   2   3   … FFFF(10进制为2^16-1)

有符号数:

正数: 0   1   2   … 7FFF(10进制127)

负数: -1      -2     -3       -4   …

FFFF   FFFE   FFFD    FFFC  …

Android4字节对齐和4k对齐 四字节宽度_无符号数_03

同理 32位宽度,不在此罗列了

 

总结:

从计算机角度看,它不知道什么叫有符号数,什么叫无符号数,什么是正数,什么是负数,只管存储二进制数,但是从使用者角度看,计算机中每个数据都是一个容器,有自己最大的宽度,可以决定是否有无符号(从而数据宽度也不同),一旦超过宽度,将会使得最高位数据被丢失

         学以致用:

分析下面C语言程序,写出程序运行结果(此题摘自程正冲的C语言深度剖析)

Int  main()
{
         char a[1000];
         int i;
         for(i=0;i<1000;i++)
         {
                   a[i]=-1-I;
         }
         printf(“%d”,strlen(a));
return 0;
}

思路:越是简单题越容易出错,很多同学看到strlen函数,哦求字符串长度,直接写个1000,

而有的同学可能会进一步思考,求字符串长度函数的本质是什么,是遇到第一个数字0的时候就输出长度,可是困惑字符数组a的哪个下标存储数组0。这里就要用到我们刚才所讲的数据宽度问题。因为数组a为字符型,宽度为一个byte,而分析for循环可知,

a[0]=-1,计算机存储的是0xff,

a[1]=-2,计算机存储0xfe,

a[127]=-128,是char类型所能存储的最小负数0x80。

当i在增1 时,a[128]的值肯定不是-129,因为一个byte字节能存储的有符号数为-128~ ~127,因此会发生下溢,最高位被丢弃,剩下的8位是0111  1111 ,即0x7f,(原因如下

(1000 0000)-(0000 0001)=(0111 1111),向第九位借了一位

I继续增大,直到a[254]=0x1,a[255]=0x0,

然后a[256]=0xff,又开始循环,但是a[255]=0即0000 0000,因此可以肯定a[0]到a[254]都不为0,而a[255]为0,所以strlen(a)长度是255.

Android4字节对齐和4k对齐 四字节宽度_数据_04

解法二:如果是选择题,也可以简略思考答案,首先依据示意图无符号数(范围从0到255共256个数)就可以得出,从a[0]=0xff,一直减1,就是绕示意圆顺时针转,一直转到a[255]=0x00,所以strlen(a)长度为255.