C/C++教程

C语言 char 127+1 问题

本文主要是介绍C语言 char 127+1 问题,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

一个字节能存下多大的整数

【无符号数】 一个字节有8位,如果全部用来表示数值,一共可以表示 2^8=256 个数 0,1,2,3,...,255

【有符号数】 如果用最高位表示符号(0表示正,1表示负),那么只剩下7位表示数值:

  1. "0000 0001" ~ "0111 1111" 表示127个正数
  2. "1000 0001" ~ "1111 1111" 表示127个负数
  3. 但是,现在还剩下 "0000 0000""1000 0000"未表示任何数,由于平时+0等于0,于是规定
    • "0000 0000" 表示 0
    • 还剩下 "1000 0000" 可以表示一个数(肯定不能是-0吧),显然应该是一个负数,而 -1 ~ -127 都已经表示了,所以用"1000 0000" 表示 -128
  4. 因此,有符号数的表示范围是:-128~127 共256个数

注:以上二进制不是反码也不是补码,均为原码

原码、反码、补码互相转换

首先注意几点:

  1. 在计算机中,数字的存储、运算都用补码进行。
  2. 并且在运算时,补码的符号位也参与运算,因为在计算机看来,这些都是数字"0"或"1", 都能参与运算。
  3. 而人要想认出这个计算结果到底是多少,就需要转化为原码才可以。

正数以及0的原码、反码、补码相同,就不多说了

负数补码与原码相互转换

将负数的【原码转为补码】,需要经历几个步骤:

假设一个8位类型的数字 -1

  1. 写出原码:符号位用1表示,如-1的原码:1000 0001
  2. 写出反码:【符号位不变】,其余各位取反,如-1的反码:1111 1110
  3. 计算补码:在反码的基础上 +1 ,如-1的补码:1111 1111

将负数的【补码转为原码】,只需要记住:"补码的补码==>原码",也就是通过计算补码的补码即可还原出原码。

如:-1的补码 1111 1111 ---[符号位不变,其余取反]---> 1000 0000 ---[+1]---> 1000 0001
image

下图来源于维基百科,是几个特殊的数字的补码

image-20220614151055902

【127+1】的运算

手算

前面说过,在计算机内部,数字的存储、运算都是以补码形式进行

那么 "127+1"的运算过程如下

  1. 127 的补码是: 0111 1111

  2. 1的补码是: 0000 0001

  3. 相加后的补码: 1000 0000 (补码运算时,符号位也参与运算)

  4. 然后,要把补码转换为人方便阅读的原码:
    image

    根据最前面说到的结论可知,1000 0000(原码) 不表示 -0 而表示 -128

同理,"127+2"的运算步骤:

  1. 127 的补码是: 0111 1111
  2. 2的补码是: 0000 0010
  3. 相加后的补码: 1000 0001 (补码运算时,符号位也参与运算)
  4. 相加结果转为原码: 1000 0001(补码) ---> 1111 1110(反码)---> 1111 1111(原码)=-127

C程序

#include <stdio.h>

int main()
{
	char a=127, b=127;
	a+=1;
	b+=2;
    printf("计算结果:%d ,%d\n", a, b); // 输出: 计算结果:-128 ,-127
    return 0;
}

去菜鸟工具验证

image-20220614135246641

要点总结

  1. 正数以及0的原码、反码、补码相同
  2. 计算机存储和运算时使用【补码】,补码运算时,符号位也参与
  3. 负数的原码、反码、补码转换过程中,符号位不变;转换过程中,即使有进位,符号位也不参与运算
这篇关于C语言 char 127+1 问题的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!