【C语言】原码 反码 补码 :混淆之谜!

发布于:2023-01-22 ⋅ 阅读:(357) ⋅ 点赞:(0)

基本了解

相信很多初学内存存储的小伙伴,对原码 反码 补码 了解是了解,可还是不会做题,这篇文章带你通透你混淆的原因,让我们开始吧 ! ! !
首先了解基本概念:不要眼高手低!

原码

直接将数值按照正负数的形式翻译成二进制就可以得到原码.
举例:1的原码→0000000000000000000000000001

反码

将原码的符号位不变,其他位依次按位取反就可以得到反码.
举例:1的原码→0000000000000000000000000001
举例:1的反码→01111111111111111111111111111110

补码

反码+1就得到补码.
举例:1的原码→0000000000000000000000000001
举例:1的反码→01111111111111111111111111111110
举例:1的补码→01111111111111111111111111111111

混淆原因

整型提升:C语言中整型运算总是至少以缺省整型类型的精度来进行的

普通话:当我们写原码时一共32个bit(比特)位,但32个bit对应的是整型类型啊!伙伴们!
牛粪配鲜花,牛马配傻瓜.一对一嘛!其他数据类型:像char,本身就一个字节 8个bit位大小,装不了32个
bit位,所以就有了整型提升.
(char先生:达咩! 达咩! 达咩!)

规则:整型提升是按照变量的类型来进行提升的。

a. 如果是无符号数,则高位直接补0;
b. 如果是有符号数,则高位全补符号位。

有符号整型提升

其实大部分小伙伴出错的原因是整型提升只了解的基本概念,还不知道怎么用,下面举例有符号的例子让你明白

负数的整形提升
char haha = -1;
根据我们提到的基本概念
-1的原码:1000000000000000000000000000001
-1的反码:1111111111111111111111111111110
-1的补码:1111111111111111111111111111111
但小伙伴们,注意啦!32个bit = 4个字节,char类型的存储空间只有一个字节
不信可以自己验证:sizeof(char)1
所以:就要发生截断:1个字节 = 8个bit位
根据C语言规定从后往前截取
因此变量haha的二进制位(补码)中只有8个比特位:
1111111
因为 char~~有符号~~char,
所以整形提升的时候,高位补充符号位,即为1
提升之后的结果是:
11111111111111111111111111111111(负数补码)
正数的整形提升
char hehe = 1;以下同理
变量hehe的二进制位(补码)中只有8个比特位:
00000001
因为 char~~有符号的~~  char
所以整形提升的时候,高位补充符号位,即为0
提升之后的结果是:
00000000000000000000000000000001(负数补码)

无符号整型提升

想一想输出什么?,为了学会赚钱娶老婆,请先想一想
#include <stdio.h>
int main()
{
    char a= -1;
    signed char b=-1;signed是有符号的意思
    unsigned char c=-1;unsigned是无符合的意思
    printf("a=%d,b=%d,c=%d",a,b,c);
    return 0;
}


下面↓解析
题目无穷,但开阔思维,才是习得之道
char a =-1;不同编译器默认选择不同,我用vs2022,默认有符号
故char a = -1结果 等于 signed char c = -1;结果
首先由有符号例子知道了-1的补码,但补充一点%d:打印原码.
所以我们还得转化成原码(肯定有人抱怨怎么这么麻烦,哈哈,拿钱甩你脸上,!)
 -1的补码:11111111111111111111111111111111
 注意啦!兄弟!char类型哦!截断哦,从原码成为补码前整型提升(原因:牛粪配鲜花→需要提升),
 所以补码为:11111111,有因为是signed有符号数
 所以高位全补符号位:补码:11111111111111111111111111111111
 反码:1111111111111111111111111111111110
 原码:1000000000000000000000000000000001
 存入char类型二进制:00000001
 因为有符号位,保留符号且输出结果
 所以打印出结果:-1


unsigned char c=-1
当我们得到-1截断的补码,接着我们就在整型提升了,上文说到整型提升的规则
如果是无符号数,则高位直接补0
那么补码:00000000000000000000000011111111
因为字符在使用之前要被转化为普通整型:字符或短整型→整型:整型提升
因为初始类型:char,只能存放八个比特位,发生截断最终二进制位:11111111
又因为unsigned使得第八位 1 变成无符号位
是无符号数,则高位直接补0:00000000000000000000000000111111111
符号位是零→是个整数 所以原码 反码 补码 相同
存入char里面的二进制序列:11111111
转化为10进制数字:255.

``

本文含有隐藏内容,请 开通VIP 后查看