数据在内存中的存储1:整形(char,short,int...)的补码

简介: 在整形家族中

①在整形家族中有:


char (一个字节)

   unsigned char

   signed char

short(int 省略)(两个字节)

   unsigned short

   signed short

int(四个字节)

   unsigned int

   signed int

long(int 省略)(四个字节)//在早期老设备int是两个字节,所以称之为长整形,而现在long与int长度一致

   unsigned long

   signed long

long long 同(八个字节)

注意:只有char类型的数据类型由不同编译器环境决定默认为无符号还是有符号

其他均默认为有符号,vs环境下char为有符号


②整形在内存中存储:补码(二进制的形式)(小提一手)



在vs中,调试内存窗口这里,是按字节为单位有序排列(这里是按十六进制(容易看),ox为十六进制前缀)


(a~f代表10~15)


两个十六进制位刚好代表一个字节八个二进制位(通过数学知识,我们只需要在对应的每八个二进制与对应的每两个十六进制相互转化就好)(其他进制就没有这么好的性质)


补码来运算,非常的方便,最主要是不影响结果


③符号与无符号:


unsigned 无符号:没有符号位,恒为正


signed 有符号:补码首位为1则为为负


其他进制的数的正负取决于首位,例如十六进制,首位0~7则位正,8~15为负,(一半数为正,一半数为负)


结合类型的字节数,导致他们拥有了一个“闭环的”取值范围


(例如char)



其他类型可类推(超出范围就会截断,-这导致出现了取值范围)


④整形在内存中以补码的形式存储.


对于正数和无符号数,他们的原码反码补码相同;


对于负数,


例如  (int)-1


原码(给人看的,直接得到到二进制数)(补码取反加一or补码减一取反)


10000000000000000000000000000001


反码(除了符号位,按位取反)


1111111111111111111111111111111111110


补码(计算机内存中看到的,计算机认识的,计算机识别的)(原码取反加一)


1111111111111111111111111111111111111


(如果强制类型转化位unsigned int 则计算机直接识别到的是补码,直接认为是正数)


补充:10000000000000000000000000000000(-2147483648)的原码是三十三位的,但是没关系,内存中是三十二位就好,毕竟字节大小限制的是补码,因为存放的是补码。


注意:其他位数的什么什么码要转化为二进制看


补充:在计算过程中,遇到整形提升和算术转化和截断甚至移位操作符,位数上升(或者补位),有符号整形补符号位,无符号补0,计算过程保持用补码,并且算术表达式最低类型为int,计算结果根据最终要存放在哪个类型中决定补充还是截断。(有时通过闭环取值范围能很好的得到结果)


额外内容:大小端字节序


(大端模式)就是数据的低位存放在高地址处,数据的高位存放在低地址处


(小端模式)就是数据的高位存放在高地址处,数据的低位存放在低地址处(VS环境)



以字节为单位从左往右地址递增,位的值大小也递增(符合习惯)(习不习惯不重要,记住这个规矩就好,并且一些编译器是大端,与此相反)(这跟指针的加法和解引用有关)


下面是一个函数来判断编译器是大端还是小端


void judge()
{
    int i=1;
    if(*((char*)&i))
        printf("小端\n");
    else
        printf("大端\n");
}
//其他序列类型被淘汰了

练习:


#include<stdio.h>
int main()
{
    unsigned char c=-1;
    printf("%d",c);
    return 0;
}

这里,-1为整形,则补码为11111111111111111111111111111111,但是是截断后为11111111(无符号255),然后要变为有符号整形int,要补充0,得到00000000000000000000000011111111,就是255.


#include<stdio.h>
int main()
{
   char a=-128;
    printf("%u",a);
    return 0;
}

这里,-128为10000000,整形提升补的是符号位1,为11111111111111111111111110000000,然后被认为是无符号打印出来,就是4294967168

int main()
{
  char a=128;
    printf("%u",a);
  return 0;
}

这里,把128(......10000000)放到char里面去,(截断后)是-128,而打印成无符号,就跟上一道题一样,先补上符号位1,然后被看做是无符号打印出来。


int main()
{
    int i=-20;
    unsigned int j=10;
    printf("%d",i+j);
    return 0;
}

这里,-20为10000000000000000000000000010100


       补码  ->111111111111111111111111111111101100      


           10为00000000000000000000000000001010


-20的补码被看作了无符号,然后与10相加,后为111111111111111111111111111111110110  


但是打印的时候计算机识别这个补码,打印为有符号(通过计算出原码知道是-10)


就是说:(需要补位的补位,截断的截断之后)不用管送到占位符那的那个补码的前世今生,根据占位符读这个码,得到多少就是多少。


最后注意了

unsigned int i;
    for (i = 9; i >= 0; i--)
    {
        printf("%u\n", i);
    }

这是一个死循环,因为0-1后,由于是无符号,它还是大于等于0的!


目录
相关文章
|
消息中间件 存储 缓存
kafka 的数据是放在磁盘上还是内存上,为什么速度会快?
Kafka的数据存储机制通过将数据同时写入磁盘和内存,确保高吞吐量与持久性。其日志文件按主题和分区组织,使用预写日志(WAL)保证数据持久性,并借助操作系统的页缓存加速读取。Kafka采用顺序I/O、零拷贝技术和批量处理优化性能,支持分区分段以实现并行处理。示例代码展示了如何使用KafkaProducer发送消息。
|
存储 编译器 数据处理
C 语言结构体与位域:高效数据组织与内存优化
C语言中的结构体与位域是实现高效数据组织和内存优化的重要工具。结构体允许将不同类型的数据组合成一个整体,而位域则进一步允许对结构体成员的位进行精细控制,以节省内存空间。两者结合使用,可在嵌入式系统等资源受限环境中发挥巨大作用。
820 12
|
监控 算法 应用服务中间件
“四两拨千斤” —— 1.2MB 数据如何吃掉 10GB 内存
一个特殊请求引发服务器内存用量暴涨进而导致进程 OOM 的惨案。
538 14
|
存储 C语言
数据在内存中的存储方式
本文介绍了计算机中整数和浮点数的存储方式,包括整数的原码、反码、补码,以及浮点数的IEEE754标准存储格式。同时,探讨了大小端字节序的概念及其判断方法,通过实例代码展示了这些概念的实际应用。
1346 1
|
数据采集 分布式计算 数据处理
Dataphin常见问题之与指定类型int不兼容如何解决
Dataphin是阿里云提供的一站式数据处理服务,旨在帮助企业构建一体化的智能数据处理平台。Dataphin整合了数据建模、数据处理、数据开发、数据服务等多个功能,支持企业更高效地进行数据治理和分析。
|
SQL 流计算 OceanBase
OceanBase CDC从热OB库采集过来的Tinyint(1)类型会默认转换成Boolean,请教一下,如果想转换成int类型,有什方法么?
【2月更文挑战第25天】OceanBase CDC从热OB库采集过来的Tinyint(1)类型会默认转换成Boolean,请教一下,如果想转换成int类型,有什方法么?
605 3
|
Python Windows
[oeasy]python076_int这个词怎么来的_[词根溯源]整数类型_int_integer_touch
本文探讨了“int”一词的起源及其与整数类型的关联。通过词根溯源,揭示“int”来源于“integer”,意为“完整的数”,与零碎的分数相对。同时分析了相关词汇如“tact”(接触)、“touch”(触摸)及衍生词,如“tangential”(切线的)、“intagible”(无形的)和“integral”(完整的、不可或缺的)。文章还结合编程语言特性,解释了Python作为动态类型、强类型语言的特点,并总结了整型变量的概念与意义。最后预告了后续内容,提供了学习资源链接。
701 11
|
存储 C语言 Python
[oeasy]python077_int类型怎么用_整数运算_integer_进制转化_int类
本文主要讲解了Python中`int`类型的应用与特性。首先回顾了`int`词根的溯源,探讨了整型变量的概念及命名规则(如匈牙利命名法)。接着分析了整型变量在内存中的存储位置和地址,并通过`type()`和`id()`函数验证其类型和地址。还介绍了整型变量的运算功能,以及如何通过`int()`函数将字符串转化为整数,支持不同进制间的转换(如二进制转十进制)。此外,文章提及了关键字`del`的使用场景,对比了Python与C语言中`int`的区别,并总结了整型与字符串类型的差异,为后续深入学习奠定基础。
537 1
|
JSON 小程序 JavaScript
小程序根据返回值的int类型渲染不同的状态
小程序根据返回值的int类型渲染不同的状态
342 0
【Java基础面试五】、 int类型的数据范围是多少?
这篇文章回答了Java中`int`类型数据的范围是-2^31到2^31-1,并提供了其他基本数据类型的内存占用和数值范围信息。
【Java基础面试五】、 int类型的数据范围是多少?