信息存储
机器级程序将存储器视为一个非常大的字节数组称为虚拟存储器,存储器的每个字节都由一个唯一的数字来标识,称为它的地址,所有可能的地址的集合称为虚拟地址空间这个虚拟地址空间只是一个展现给机器级程序的概念性映像。实际的实现是将随机访问存储器(RAM)、磁盘存储器、特殊硬件和操作系统软件结合起来,为程序提供一个看上去统一的字节数组。
进制转换
10转16
该方法仅对十进制的2的整次数幂
比如十进制512,为2^9。把9写成1*i+4*j,即1*1+4*2。即其16进制为2开头后跟2个零。
其他有关进制转换的方法不详细介绍仅用事例说明
下列图来源某培训机构
任意进制转十进制
十进制转任意进制
8421码
反码,补码,原码
字
每台计算机都有一个字长,指明整数和指针数据的标称大小。大多数计算机的字长是32位,那么它有2∧32种地址大概刚超过4GB大小,即它的虚拟地址空间最大这么多。
数据大小
许多机器能处理单字节,2,4,8字节(64位)。对于32位机器他会把64位数据处理成一系列32位操作的代码。
程序员应该力图使他们的程序在不同的机器和编译器上是可移植的,比如声明一个int(32位大小)类型的程序对象能被用来存储一个指针,但是在一台64位机子运行该程序可能出问题
寻址和字节顺序
对于跨越多字节的程序对象,我们必须建立两个规则:
- 这个对象的地址是什么
- 在储存器中如何排列这些字节
地址是什么
几乎所有机器,对象的地址为所使用字节最小的地址,例如:一个int类型数据有四个字节地址分别为0x001,0x002,0x003,0x004,那么这个int数据的地址为0x001。如何排列
大端和小端存储(注意是数据存储!非地址)
小端存储:
机器在存储器中按照最低有效字节到最高有效字节的顺序存储对象,也就是说最低有效字节在前面,Intel的机器就是这样
大端存储:
机器按照最高有效字节到最低有效字节的顺序存储对象
例如:
有一int类型数据,其地址为0x100,其保存的16进制数据为0x01234567(16进制每两个数字用1字节储存,01是高字节,67是低字节)
通常机器所使用的字节顺序是不可见的
但是有时,字节顺序可能成为问题
1,在不同类型的机器之间通过网络传输二进制数据时,小端法机器产生的数据到大端法的机器变成反序的.为了避免这个问题,代码编写必须遵守字节顺序的规则
2,阅读整数数据的字节序列时字节顺序也很重要
3,当编写规避正常的类型系统的程序时。(强制类型转换)
布尔代数
位向量:有固定长度为w,由0和1组成的串
&
~取反
|
^
&对|有分配律:a&(b|c)=(a&b)|(a&c)
|对&也有分配律:a|(b&c)=(a|b)&(a|c)
位向量可用于表示有限集合。我们可以用位向量[aw1,.....,a1,a0]编码任何子集A∈{0,1,....,w-1}其中ai=1当且仅当i∈A。例如,(记住我们是记aw-I写在左边,而将a0写在右边,即写的方向相反),位向量a=[01101001](最后一位为1,说明集合中有0,倒数第4为1,说名集合有3)表示集合A={0,3,5,6},而b=[01010101]表示集合B={0,2,4,6}
这样我们可以用|,&对应并,交,对集合操作。
比如a&b=[01000001],A交B={0,6}。
位运算
掩码运算
先有一个掩码比如0xFF,这个掩码可以认为是一个8位的二进制,且每位都是1
现在有一个16进制数A
A&0xFF,这个表达式的意思是,A变成二进制保留最后8位的值,前面的都变成0,实际是把二进制的每位对应地做布尔运算.
C语言的逻辑运算
逻辑运算中TRUE为任意非零,FALSE为0
Expression Result
!0x41 0x00
!0x00 0x01
!!0x41 0x01
0x69 && 0x55 0x01
0x69 || 0x55 0x01
C语言位移运算
一般机器支持两种右移运算:
逻辑右移:向右移动,丢弃右端,左端补0
算数右移:向右移动,丢弃右端,左端补最高有效位的值
比如[01100011]>>4 结果是[00000110]
[10010101]>>4 结果是[11111001]//红色1是最高有效位
注意
对于无符号数据必须用逻辑右移
对于有符号数据,两个都可以,但这样存在可移植性问题,然而几乎所有机器用的是算数右移
Java中X>>k是算数右移,X>>>k是逻辑右移
对于w位的数字,对他位移k位,其最终位移量是k mod w,C语言用这种方法规避大数字的位移量
位移运算的优先级
不用管那么多加括号就好