开头:本章研究在计算机上如何表示数字和其它形式数据的基本属性,以及计算机对这些数据执行操作的属性。
注意:这部分谈到的内存,并不是指硬件中的内存条,而是在《计算机系统漫游》章节中的:【 虚拟内存】:是对主存、磁盘、I/O设备的抽象表示
下面是书本的描述:
- 字节(byte):大多数计算机使用8位的块,或叫做字节(byte),来作为 最小的可寻址的内存单位,而不是访问存储器中单独的位
- 虚拟内存:把内存看作成一个非常大的字节数组。
- 地址:内存中的每个字节都由一个唯一的数字来标识。一般是用十六进制来表示。
- 虚拟地址空间:所有可能地址的集合。
这里是我的总结:
字节:存储空间的最小单位,描述数据占据多少空间,就用字节来数表示。大多数机器中,1个字节=8位
地址:内存中的每个字节都由一个唯一的数字来标识,成为它的地址;理解为门牌号。
疑问: 地址占不占用空间?
关于字长:平时说的32位系统、64位系统,34 跟 64 表示字长。
本节先这么理解字长:
## 推导过程
1024 = 2^10
1EB=1024PB
1PB=1024TB
1TB=1024GB
1GB = 1024MB
1MB=1024KB
1KB = 1024B
1GB = (1024 * 1024 * 1024) B = 2^30B
所以:
2^32 = 2^30 * 2^2 = 4GB
2^64 = 2^30 * 2^30 * 2^4 = 16EB
16EB = 16 * 1024 *1024*1024 = 17179869184GB
C语言数据类型中在不同字长系统下的占据字节数如下:
二进制示法太冗长,而使用十进制表示法,与位模式的互相转化很麻烦。替代的方法是:十六进制数:使用数字”0″”9″,以及字符”A””F”来表示16个可能的值。
- 0x 或 0X 开头表示
- 字符”A”~”F”既可以是大写,也可以是小写,至是 大小写混合
2个十六进制数字就表示一个字节:因为用4个二进制数字就可以表示1个16进制数字,因此2个十六进制=2*4=8个二进制 =1个字节
二进制转十六进制:**从右往左,每四位为一截,划分,左边不足四位,补0**
十六进制转二进制进制:分别将每个16进制分别转换成对应的二进制即可。例如 0x8A = 1000 1010
十进制转二进制:除2 取余,再反转排序
二进制转十进制:abcd.efg(2)=d20+c21+b22+a23+e2-1+f2-2+g* 2-3
对于跨越多字节的程序对象,需建立两个原则:这个对象的地址是什么?以及在内存中如何排列这些字节。
例如,假设一个类型为int的变量x的地址为 0x100,x的4字节将被存储在内存的 0x100、0x101、0x102 和 0x103 位置。
- 大端法:高位存储在低地址
- 小端法:低位存储在低地址
不同的系统有各自的表示规则,
两种不同排序规则下的字节序列存储如下:
关于设定好字节顺序的两种场景
网络上的数据流是字节流,对于一个多字节数值,在进行网络传输的时候,先传递哪个字节?也就是说,当接收端收到第一个字节的时候,它是将这个字节作为高位还是低位来处理呢?发送方要根据接收方的字节排序规则,来确定字节的发送顺序
网络字节序定义:收到的第一个字节被当作高位看待,这就要求发送端发送的第一个字节应当是高位。而在发送端发送数据时,发送的第一个字节是该数字在内存中起始地址对应的字节。可见多字节数值在发送前,在内存中数值应该以大端法存放。
判断机器大小端法例子
#include
int main()
{
int a = 0x12345678;
char i = a;
printf("%x", i);
return 0;
}
定义1个十六进制的数据,数据类型为int型,再定义一个char类型的数据,int数据类型的大小为4个字节,而char类型的数据为1个字节,
因此将int类型的数据赋值给char时会丢失三个字节的数据,char类型中存储的是int类型中低地址的数据,
这时候char类型获取的数据输出以后,若是输出的是12那就说明你低地址位置的数据是12,那就说明你的数据是大端存储,若是输出的结果是78那当前条件下就是小端存储。
输出结果:78,即该 centos系统采用小端法存储
计算机系统的一个基本概念就是, 从机器的角度来看,程序仅仅只是字节序列。机器没有关于原始源程序的任何信息,除了可能有些用来帮了助调试的辅助表以外。
不同的机器类型使用不同的且不兼容的指令和编码方式。即使是完全一样的进程,运行在不同的操作系统上 也会有不同的编码规则,因此 二进制代码是不兼容的。 二进制代码很少能在不同机器和操作系统组合之间移植。
6.1 位级运算
符号 表述 说明 ! OR & AND ~ NOT 取反 ^ EXCLUSIVE-OR 异或 位数相同得到0,位数相反得到1
举例子:
将十六进制转换成二进制并执行二进制运算后,再转回十六进制。
什么是掩码?:
简单来说掩码就是一串二进制码。比如:00000101。就是个数字。掩码的作用是用来存储和操作”状态(State)”。大致用法和逻辑总结:
- 用二进制码存储状态,
- 通过位运算(&, |, ^, ~, >>, << 等)来操作状态。
为什么使用掩码?
为什么使用掩码其实本质是为什么使用二进制和位运算。
在计算机编程中, 直接做二进制运算——即位运算的效率更高。而且表达上更简洁。
哪里有使用?
熟悉Java的都知道,java.util.concurrent JUC工具包中,大量的类使用位级运算,保存状态或结果信息,例如AbstractQueuedSynchronizer的成员变量:state,可重入读写锁ReentrantReadWriteLock就是利用了左移右移运算,同时在高、低位存储了读/锁的状态
6.2 逻辑运算
逻辑运算符号 表述 说明 || OR 逻辑或 && AND 逻辑与 ! NOT 取反
注意:逻辑运算跟位级运算容易混淆,但是他们的功能完全不同。
6.3 移位运算
左移K位 : 按二进制形式把所有的数字向左移动K位,高位舍弃,低位的空位补零。
数字意义:在数字没有溢出的前提下,对于正数和负数,左移一位都相当于乘以2的1次方, 左移n位就相当于乘以2的n次方
4<<2:表示10进制4左移2位。结果:0000 0100<<2 得到:0001 0000="16" < code></2:表示10进制4左移2位。结果:0000>
也称为无符号右移。
右移K位 : 低位舍去K位,高位补上K个0
对参数x:0110 0011 ,逻辑右移4位,结果:0000 0110
右移K位 : 低位舍去K位,高位补上K个x,这个x(符号位)是移位后最高位的那个值
对参数x:1001 0101,算术右移4位,
右移四位后:1001 ,此时最高位是1
补充K个最高位值后:1111 1001
Original: https://www.cnblogs.com/knowledgeispower/p/16690684.html
Author: 拿了桔子跑-范德依彪
Title: 4 信息的表示和处理_信息存储
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/585086/
转载文章受原作者版权保护。转载请注明原作者出处!