作者:爱弹吉他的小奔同学
专栏:《C语言》
仓库:gitee(所有的代码都在这个仓库里面)
如果感觉学累了,那么就看一个视频放松一下吧,猜猜点进去你会看到什么(视频)
我向往以后悠闲的生活,但现在的我们正处于需要努力的年华
点赞收藏关注啦啦啦啦啦
对于原码、反码、补码之间的转换就不多说了
int a = 20;
int b = -10;
20是正数
原码:0000 0000 0000 0000 0000 0001 0100
反码:0000 0000 0000 0000 0000 0001 0100
补码:0000 0000 0000 0000 0000 0001 0100
-10是负数
原码:1000 0000 0000 0000 0000 0000 1010
反码:1111 1111 1111 1111 1111 1111 0101
补码:1111 1111 1111 1111 1111 1111 0110
因为过于麻烦,所以我们写成十六进制
20
原码:0x00 00 00 14
反码:0x00 00 00 14
补码:0x00 00 00 14
-10
原码:0x80 00 00 0a
反码:0x80 00 00 0a
补码:0xff ff ff f6
通过内存显示,对于整型,在内存中是以补码的二进制序列储存的,20储存
0x00 00 00 14
,-10储存0xff ff ff f6
为什么要使用补码呢?
原码按位取反+1——>补码
补码按位取反+1——>原码
在计算机系统中,数值一律用补码来表示和存储,原因在于,使用补码,可以将符号位和数值域统一处理;
同时,加法和减法也可以统一处理(CPU只有加法器)此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路
举一个例子:
5 - 10 = -5
5是
0x00 00 00 05
-10是0xff ff ff f6
相加得
0xff ff ff fb
,取反+1得原码0x80 00 00 05
,对应的数是-5,加法和减法都可以统一这样处理,所以我们使用补码
大小端介绍
我们可以看到对于a和b分别存储的是补码。但是我们发现顺序有点不对劲。
这是又为什么?先了解一下大小端的概念
大端(存储)模式,是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中;
小端(存储)模式,是指数据的低位保存在内存的低地址中,而数据的高位,保存在内存的高地址中;
难以理解就看接下来的图
我们来探究一下对于
0x11 22 33 44
(补码)这个数据在内存中储存的形式是什么
我们以字节为单位来讨论数据储存于内存中的形式
是颠倒的,实际上就是数据的低位保存在内存的低地址,数据的高位保存在内存的高地址中,这叫小端字节序存储
那么相反,数据的低位保存在内存的高地址,数据的高位保存在内存的低地址中,这叫大端字节序存储
注意:
对于一个字节大小的类型,比如char,它的存储是没有顺序可言的,因为有顺序的最低也要两个及其以上字节大小的类型
就比如short,int等,这些都是有顺序的
那么什么时候是以大端存储的?什么时候是以小端存储的?
这跟硬件有关,也就是跟电脑有关,跟编译器没有什么关系
写个程序来判断当前机器是大端还是小端?
#include
//函数一
int judge_if_endian()
{
int a = 1;
char* p = (char*)&a;
*p = 0;//改变a的低地址放的数据为00
//如果大端——00 00 00 01,则仍为00 00 00 01
//如果小端——01 00 00 00,则变为00 00 00 00
//判断a是否被改变
if (a == 1)
return 0;
else if (a == 0)
return 1;
}
//函数二
int judge_if_endian()
{
int i = 1;
return (*(char *)&i);
//看看首地址是01还是00
//01则是小端,00则是大端
}
int main()
{
int a = judge_if_endian();
//返回0则为大端,返回1则为小端
if (a == 0)
printf("该电脑是大端字节序存储");
else if(a == 1)
printf("该电脑是小端字节序存储");
return 0;
}
配套练习