C语言之整数存储底层逻辑用法解读

📅 发布时间:2026/8/23 22:53:30
C语言之整数存储底层逻辑用法解读 1.原码二进制表示法。最高位为符号位表示正负剩下位为数值位表示数值大小。例如以8位举例10的原码00001010-10的原码100010102.反码符号位不变其余位取反。例如以8位举例10的反码00001010-10的反码11110101正数的反码原码3.补码反码1。例如以8位举例10的补码00001010-10的补码11110110正数原码、反码、补码都相等负数原码 - 补码符号位不变其余位取反1补码 - 原码方法一-1符号位不变其余位取反方法二符号位不变其余位取反1二、整数存储1.计算机中的原反补规则所有的整型数据在计算机中都已补码的形式存储和运算。计算机在处理整型数据时会先将其看作int类型进行处理若超出int类型的范围则将其看作long long型进行处理。例如char a -10;计算机首先申请了1个字节的空间并将这篇空间命名为a-10的补码为11111111 11111111 11111111 11110110将这个补码存入a这片空间因为a只有1个字节所以只能存入最后一个字节即11110110。char b 10;计算机首先申请了1个字节的空间并将这篇空间命名为b10的补码为00000000 00000000 00000000 00001010将这个补码存入a这片空间因为a只有1个字节所以只能存入最后一个字节即00001010。2.有符号/无符号整数类型在计算机中char/short/int/long/long long属于有符号signed的整数类型此外计算机中还提供了一种无符号unsigned的整数类型。类型格式控制符比特位使用规则大小Byte范围特殊值有符号signed可写可不写的整数家族char%hhd/%c1位符号位 7位数值位1Byte-2^7~2^7-110000000-2^7short%hd1位符号位 15位数值位2Byte-2^15~2^15-110000000 00000000-2^15int%d1位符号位 31位数值位4Byte-2^31~2^31-110000000 00000000 00000000 00000000-2^31long%ld1位符号位 31位数值位4Byte-2^31~2^31-110000000 00000000 00000000 00000000-2^31long long%lld1位符号位 63位数值位8Byte-2^63~2^63-110000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000-2^63无符号unsigned的整数家族unsigned char%hhu8位数值位1Byte0~2^8unsigned short%hu16位数值位2Byte0~2^16unsigned int%u32位数值位4Byte0~2^32unsigned long%lu32位数值位4Byte0~2^64unsigned long long%llu64位数值位8Byte0~2^64以char为例char1位符号位 7位数值位数值unsigned char8位数值位数值0 1111111127011111111270 111111012601111110126............0 000000110000000110 000000000000000001 0000000-128100000001281 0000001-1100000011291 0000010-210000010130............1 1111110-1261 11111102541 1111111-12711111111255char1个符号位7个数值位最大值 1270 1111111最小值 -1281 1111111unsigned char8个数值位最大值 25511111111最小值 000000000因为char类型中10000000没有别的数可以表示计算机强制规定它为最小值-2^7-128。同理short类型中计算机强制规定10000000 00000000为最小值-2^15int和long类型中计算机强制规定10000000 00000000 00000000 00000000为最小值-2^31long long类型中计算机强制规定10000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000为最小值-2^633.相同字节大小转换12345678910111213141516171819202122232425262728293031323334353637intmain() {//-10的原码:10000000 00000000 00000000 00001010//-10的反码:11111111 11111111 11111111 11110101//-10的补码:11111111 11111111 11111111 11110110chara -10;//只有一个字节的空间只能存放下最后一个字节:11110110unsignedcharb -10;//只有一个字节的空间只能存放下最后一个字节:11110110printf(a%hhd,b%hhd\n, a, b);/*a:111101101.按照%hhd(有符号char类型)的格式输出所以要将11110110看作是1个符号位7个数值位2.将补码转换成原码:11110110-10001010(符号位是1为负数;负数的原码补码-1再符号位不变其余位取反)3.将原码转换成十进制:10001010--10b:111101101.按照%hhd(有符号char类型)的格式输出所以要将11110110看作是1个符号位7个数值位2.将补码转换成原码:11110110-10001010(符号位是1为负数;负数的原码补码-1再符号位不变其余位取反)3.将原码转换成十进制:10001010--10*/printf(a%hhu,b%hhu\n, a, b);/*a:111101101.按照%hhu(无符号char类型)的格式输出所以要将11110110看作是8个数值位2.将补码转换成原码:11110110-10001010(正数的原码、反码、补码相同)3.将原码转换成十进制:10001010-138b:111101101.按照%hhu(无符号char类型)的格式输出所以要将11110110看作是8个数值位2.将补码转换成原码:11110110-10001010(正数的原码、反码、补码相同)3.将原码转换成十进制:10001010-138*/return0;}4.不同字节大小转换1小字节转大字节符号位不变数值位不变其余位补符号位的数字。123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051intmain() {//-10的原码:10000000 00000000 00000000 00001010//-10的反码:11111111 11111111 11111111 11110101//-10的补码:11111111 11111111 11111111 11110110chara -10;//只有一个字节的空间只能存放下最后一个字节:11110110unsignedcharb -10;//只有一个字节的空间只能存放下最后一个字节:11110110printf(a%hd,b%hd\n, a, b);/*a:11110110 - a的类型是有符号char类型符号位:11.按照%hd(有符号short类型)的格式输出所以要先将11110110扩充为2个字节:11110110-11111111 11110110(符号位不变数值位不变其余位补符号位的数字即补1)2.将11111111 11110110看作是1个符号位15个数值位3.将补码转换成原码:11111111 11110110-10000000 00001010(符号位是1为负数;负数的原码补码-1再符号位不变其余位取反)4.将原码转换成十进制:10000000 00001010--10b:11110110 - b的类型是无符号char类型符号位:01.按照%hd(有符号short类型)的格式输出所以要先将11110110扩充为2个字节:11110110-00000000 11110110(符号位不变数值位不变其余位补符号位的数字即补1)2.将00000000 11110110看作是1个符号位15个数值位3.将补码转换成原码:00000000 11110110-00000000 11110110(符号位是0为正数;正数的原码、反码、补码相同)4.将原码转换成十进制:00000000 11110110-246*/printf(a%hu,b%hu\n, a, b);/*a:11110110 - a的类型是有符号char类型符号位:11.按照%hu(无符号short类型)的格式输出所以要先将11110110扩充为2个字节:11110110-11111111 11110110(符号位不变数值位不变其余位补符号位的数字即补0)2.将11111111 11110110看作是16个数值位3.将补码转换成原码:11111111 11110110-11111111 11110110(正数的原码、反码、补码相同)4.将原码转换成十进制:11111111 11110110-65526b:11110110 - b的类型是无符号char类型符号位:01.按照%hd(有符号short类型)的格式输出所以要先将11110110扩充为2个字节:11110110-00000000 11110110(符号位不变数值位不变其余位补符号位的数字即补0)2.将00000000 11110110看作是16个数值位3.将补码转换成原码:00000000 11110110-00000000 11110110(正数的原码、反码、补码相同)4.将原码转换成十进制:00000000 11110110-246*/return0;}2大字节转小字节直接强行截取。1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950intmain() {//-10的原码:10000000 00000000 00000000 00001010//-10的反码:11111111 11111111 11111111 11110101//-10的补码:11111111 11111111 11111111 11110110shorta -10;//只有两个字节的空间只能存放下最后两个字节:11111111 11110110unsignedshortb -10;//只有两个字节的空间只能存放下最后两个字节:11111111 11110110printf(a%hhd,b%hhd\n, a, b);/*a:11111111 111101101.按照%hhd(有符号char类型)的格式输出所以要先将11111111 11110110截取为1个字节:11111111 11110110-111101102.将11110110看作是1个符号位7个数值位3.将补码转换成原码:11110110-10001010(符号位是1为负数;负数的原码补码-1再符号位不变其余位取反)4.将原码转换成十进制:10001010--10b:11111111 111101101.按照%hhd(有符号char类型)的格式输出所以要先将11111111 11110110截取为1个字节:11111111 11110110-111101102.将11110110看作是1个符号位7个数值位3.将补码转换成原码:11110110-10001010(符号位是1为负数;负数的原码补码-1再符号位不变其余位取反)4.将原码转换成十进制:10001010--10*/printf(a%hhu,b%hhu\n, a, b);/*a:111101101.按照%hhu(无符号char类型)的格式输出所以要先将11111111 11110110截取为1个字节:11111111 11110110-111101102.将11110110看作是8个数值位3.将补码转换成原码:11110110-11110110(正数的原码、反码、补码相同)4.将原码转换成十进制:11110110-246b:111101101.按照%hhu(无符号char类型)的格式输出所以要先将11111111 11110110截取为1个字节:11111111 11110110-111101102.将11110110看作是8个数值位3.将补码转换成原码:11110110-11110110(正数的原码、反码、补码相同)4.将原码转换成十进制:11110110-246*/return0;}总结以上为个人经验希望能给大家一个参考