3.计算机中信息的存储
1. 大多数计算机使用字节作为最小的可寻址的存储器单位。机器级程序将存储器视为一个非常大的字节数组,称为虚拟存储器。存储器的每个字节都有一个唯一的数字来标识,称为它的地址,所有可能的地址的集合称为虚拟地址空间,其实际的实现是将随机访问存储器(RAM)、磁盘存储器、特殊硬件和操作系统软件结合起来,为程序提供一个看上去统一的字节数组。
2. 小端:最低有效字节在最前面的方式;
大端:最高有效字节在最前面的方式。
举例:假设地址0x100处,存储着0x01234567,
地址 | 0x100 | 0x101 | 0x102 | 0x103 |
小端 | 67 | 45 | 23 | 01 |
大端 | 01 | 23 | 45 | 67 |
3. 位向量表示有限集合:用位向量[aw-1,…,a1,a0]编码任何子集A∈{0,1,…,w-1},其中ai=1当且仅当i∈A。
举例:位向量a=[01101001]表示集合A={0,3,5,6},b=[01010101]表示集合B={0,2,4,6},布尔运算a&b
分别对于集合的并和交,而~对应于集合的补,则a&b=[01000001],而A∩B={0,6}。
4. 逻辑右移:x>>k,在左端补k个0;
算术右移:x>>k,在左端补k个最高有效位的值。
当k≥w位时:在许多机器上,当移动一个w位的值时,移位指令只考虑位移量的低log2w位,实际上就是k%w。例如,在32位机器上计算 int i=0x12345678 << 32,36,40,则分别是移动0、4和8位。
举例:(蓝色斜体为填充的值)
操作 | 值 | 值 |
参数x | 01100011 | 10010101 |
x<<4 | 00110000 | 01010000 |
x>>4(逻辑右移) | 00000110 | 00001001 |
x>>4(算术右移) | 00000110 | 11111001 |
对于无符号数据,右移必须是逻辑的;对于有符号数据,两种右移都可以,不过几乎所有的编译器都对有符号数据使用算术右移,且许多程序员也都假设机器会使用这种右移。
C语言中,并没有明确定义应该使用哪种类型的右移;Java中,对于如何进行右移有明确定义,表达式x>>k表示算术右移,x>>>k表示逻辑右移。
5. 整型数据类型:32位和64位机器中,C语言整型的范围除了long,都是一样的。其中,long long类型是在ISO99中引入的,需要至少8个字节表示。C和C++都支持有符号和无符号数,Java只支持有符号数。
补码:补码用来表示有符号数,其最高位为符号位,权重为-2w-1。
反码:最高有效位的权重是-(2w-1-1)而不是-2w-1。
原码:最高位是符号位。
注意:+0的原码和反码都为0000;-0的原码中为1000,反码为1111;0的补码中为0000。