由一道笔试题想到的:原码反码和补码

来源:互联网 发布:linux下启动oracle 编辑:程序博客网 时间:2024/05/18 02:47

由一道笔试题想到的:原码反码和补码

这是我从一位CSDN网友的博客上边偶然发现的一道华为笔试题,博主给出了正确答案,但是我对博主的分析有点不太理解。

我们抛开程序的正确性不谈(没有给指针分配空间怎么能对指针进行解引用呢?),仅仅分析一下程序的输出结果。

如果您对原码反码补码的知识非常熟悉或者非常不熟悉,请都跳过下边这段文字直接看对程序的分析,因为我并不想把这篇文章写成对原码反码补码的教学文章。仅仅是想借程序巩固一下这方面的知识。

首先,我们需要分析一下-130在内存中的二进制存储方式。这就引出了有符号整数在内存中的存储方式:有符号整数在内存中是以补码形式存储的

首先我们给出原码,反码和补码的定义:原码即有符号整数所对应的二进制数,正数的反码和本身一样,负数的反码是对应的原码除符号位以外,其它的数位依次取反,正数的补码和本身一样,负数的补码是对应的反码在末位加1

计算机中存储方式为补码的原因是为了使减法可以当做加法来算。

其实,如果不采用补码的形式存储,内存中会出现 +0 和 -0,这一现象可以在下边的例子中看到。

举个简单的例子:

如果计算机以8位的方式存储有符号整数,则

原码 反码 补码

1 0000 0001 0000 0001 0000 0001

-1 1000 0001 1111 1110 1111 1111

0 0000 0000 0000 0000 0000 0000

如果是反码存储的话,-1 + 1 = 1111 1111, 1111 1111是 1000 0000 的反码,也就是 -0

我们接着来分析这个程序:

-130在内存中以补码形式存储,在我的系统中,int类型占4个字节(到今天我也不知道到底是什么东西影响了int的大小,书上说和操作系统的位宽有关,但是我在32位和64位下都试了,结果都是4个字节,或许和编译器有关?如果哪位朋友知道请告知我!谢谢了!)。那么,-130的原码为: 1000 0000 0000 0000 0000 0000 1000 0010,反码为:1111 1111 1111 1111 1111 1111 0111 1101,补码为:1111 1111 1111 1111 1111 1111 0111 1110

由于*p的数据类型是char,将-130赋值给*p会将数据从低位截断,结果是:0111 1110,那么,输出*p的时候,系统会将数据自动补上0,也就是说,会输出0000 0000 0000 0000 0000 0000 0111 1110。即126

原创粉丝点击