目录
1、整数在内存中的存储
原码、反码、补码:
2、大小端:
前提须知:
大小端存储方式:
字节的顺序:
概念:
判断机器是大端还是小端:
代码展示:
代码优化1.0:
编辑
代码优化2.0:
1、整数在内存中的存储
原码、反码、补码:
整数的2进制表示方法有三种,即原码、反码和补码三种表示方法均有符号位和数值位两部分。
符号位都是用0表示"正",用1表示"负”。
数值位最高位的一位是被当做符号位,剩余的都是数值位。
例如:
int a = 5;
//00000000 00000000 00000000 00000101 5的原码
//00000000 00000000 00000000 00000101 5的反码
//00000000 00000000 00000000 00000101 5的补码
而-5的原码是在5的原码基础上,将符号位从0改成1
int a = -5;
//10000000 00000000 00000000 00000101 -5的原码
//11111111 11111111 11111111 11111010 -5的反码
//11111111 11111111 11111111 11111011 -5的补码
原码到补码是经过了取反变为反码,在反码的基础上+1得到补码。
而补码转化为原码也是如此,进行反取后+1
注意补码的取反不是反码。
对于整形来说:数据存放内存中其实存放的是补码。
为什么呢?
在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理:同时,加法和减法也可以统一处理(CPU只有加法器)此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。
2、大小端:
前提须知:
虽然内存中存储是使用二进制形式进行存储,但是在内存中,数据是以十六进制的形态在内存块中进行展示的。
例如:
int a = 11;
//00000000 00000000 0000000 00001011
如图是11的二进制原码。
而通过四个二进制数位一个十六进制数位的转化,得到:
0x 00 00 00 0b
转化详情:http://t.csdn.cn/kg9co
而在内存中的展示:
又例如:
int b = 0x11223344:
在内存中的展示:
以上两个例子都能让我们直到,在内存数据块中,数据是以十六进制的方式进行展示的。
但是我们又从以上两个例子中,展示的方式或者说顺序和我们知晓的十六进制数位有所差异,或者说顺序相反,这是这么回事呢?
其实这里涉及了,大小端的存储方式。
大小端存储方式:
字节的顺序:
当一个数值超过1个字节的时候,存储在内存中有存储的顺序问题,而内存中的存储单元是1字节的。
概念:
在内存中的数据可以拥有无数种存储方式,但是无论这么存储,关键在于存进去和取出来的简易程度。
举例:
图上四种方式都是在理论中成立的存储方式,但是只有前两个存储方式是真确的!
而这两种存储的方式分别叫做大端字节序存储和小端字节序存储,简称大端和小端。
从上图的操作来看,大端存储是指原封不动的在内存块中展示,而小端存储则是将十六进制进行倒序在内存块中展示。
但是在数据内存中来看:
- 大端字节序:将一个数值的低位字节序的内容存储到高地址处,高位字节序的内容存储到低地址处。
- 小端字节序:将一个数值的低位字节序的内容存储到低地址处,高位字节序的内容存储到高地址处
- 注意:在进制中,左端是高位,右端是低位。
- Vs中采用的是小端字节数存储
判断机器是大端还是小端:
判断编译器是大端存储还是小端存储,可以通过看第一个字节数是否是理想中的数据。
例如,我们这里使用整型数字1进行判断
如若编译器是小端,那么第一个字节便是1,反之,如果是大端,那么第一个字节便是0
代码展示:
*(char*)&a;
- &a是拿出a的地址,a的地址是从起始位置开始的也就是在内存中存储的第一个字节开始的。
- char*表示取第一个字节,最前面的*表示进行解开第一个字节
代码优化1.0:
代码优化2.0: