整型在内存中的存储,整型最大值最小值的推导,以及大小端的介绍

简介: 整型在内存中的存储,整型最大值最小值的推导,以及大小端的介绍

整数在内存中的存储

  • 我们知道C语言有以下基本的整型类型:
char  //字符型
short   //短整型
int   //整型
long  //长整型
long long   //更长的整型
  • 我们可以用操作符sizeof和在<limits.h>头文件下,可以查看到各基本数据类型的所占字节的大小以及整形所能表示的范围
  • 注:
  • 由于char本质上是以ASCII码值存储,而ASCII是一个整数,故也将char归为整型
  • short 等价于 signed short,int 等价于 signed int,long 等价于 signed long,long long 等价于 signed long long,但是C语言标准没有明确规定char、signed char,unsigned char之间的关系,但一般来说,char与signed char等价
  • unsigned和signed的区别:signed的最高位为符号位。而unsigned的所有位都是数值位,所表示的数只能是非负数
  • 对于二进制、八进制、十六进制及其计算还不太了解的,建议看看二进制、八进制、十六进制与十进制的相互关系
数据类型 占字节数 整型表示的最大范围
char 1 -128~127
unsigned char 1 0~2 * CHAR_MAX + 1
short 2 -32768~32767
unsigned short 2 0~2 * SHRT_MAX + 1
int 4 -2147483648~2147483647
unsigned int 4 0~2 * INT_MAX + 1
long 4/8 -2147483648~2147483647 / -9223372036854775808~9223372036854775807
unsigned long 4/8 0~2 * INT_MAX + 1 / 0~2 * LLONG_MAX + 1
long long 8 -9223372036854775808~9223372036854775807
unsigned long long 8 0~2 * LLONG_MAX + 1

原码,反码,补码

  • 计算机内部的二进制数都是以补码储存的
  • 正数的原码就是补码。
  • 反码即将原码的所有数取反,即1变0,0变1。
  • 负数原码(由十进制转二进制计算出来的数)与补码的关系:原码(保持符号位不变) -> 反码 -> 反码+1 -> 补码
  • 如将负数 1001 0111 变为补码:1001 0111 -> 1110 1000 -> 1110 1001
  • 举个例子:
int num_1 = 10;
/*
在内存中存储的二进制序列为
0000 0000 0000 0000 0000 0000 0000 1010
*/
int num_2 = -10;
/*
在内存中存储的二进制序列为
原码 :1000 0000 0000 0000 0000 0000 0000 1010
反码 :1111 1111 1111 1111 1111 1111 1111 0101
补码 :1111 1111 1111 1111 1111 1111 1111 0110
*/
  • 那为什么计算机中存储的是反码呢?
  • 使用补码可以将符号位和数值域统一处理
  • 同时也可以将加法和减法做统一处理(CPU只有加法器)

整数最大值最小值的推导

  • 了解了原码,反码,补码的概念后,我们就可以推导各整型的最大最小值了,这里我以char型为例:
  • signed char有符号字符型,最高位为符号位
  • 由于正数的补码就是原码,最大值很容易得到,即:0111 1111 = 127
  • 而对于最小值,可能有很多小伙伴会疑惑最小值为什么是-128而不是-127,这里我们来讨论一下:

  • 我们可以发现char类型中,-128的原码和补码都是1000 0000,同时,这也是-0的原码,但-0和0表示的是同一个数,因此**-0就是没有意义的**,那么1000 0000这个数怎么办,为了避免浪费,我们就将它顺延到后面去,因此char的最小值,就是-127-1 = -128
  • 其他整数类型也是同样的推导。

相关例题

  • 注:建议先了解整型提升的相关知识,这样理解会更加深刻。

Eg1

#include<stdio.h>
int main()
{
  char num_1 = 127 + 1;
  /*
    整型提升:
    127:  0000 0000 0000 0000 0000 0000 0111 1111
    1  :  0000 0000 0000 0000 0000 0000 0000 0001
    和 :  0000 0000 0000 0000 0000 0000 1000 0000
    由于截断
    num_1:1000 0000 = -128
  */
  printf("num_1 = %d\n", num_1);
  /*
    num_1:1000 0000
    整型提升:1111 1111 1111 1111 1111 1111 1000 0000
    反码:    1111 1111 1111 1111 1111 1111 0111 1111
    原码:    1000 0000 0000 0000 0000 0000 1000 0000
    因此num_1 = -128
  */
  char num_2 = -128 - 1;
  /*
    整型提升:
    -128:1111 1111 1111 1111 1111 1111 1000 0000
    -1:  1111 1111 1111 1111 1111 1111 1111 1111
    和:1 1111 1111 1111 1111 1111 1111 0111 1111
    由于截断
    num_2:0111 1111 = 127
  */
  printf("num_2 = %d\n", num_2);
  return 0;
}

  • 通过这一题,我们可以发现,char类型的数据其实可以构成这样的循环:

Eg2

int main()
{
  char a[1000] = {0};
  int i=0;
  for(i=0; i<1000; i++)
  {
     a[i] = -1-i;
  }
  printf("%d",strlen(a));
  return 0;
}
  • 我们知道strlen碰到字符‘\0’就会停止读取,而‘\0’的ASCII值为0,因此这一题,我们就是要看当i为多少时,a[i] == 0
  • 由上面的循环图,我们知道,a[i]应该依次被赋值为 -1,-2,-3……-128,127,126……0
  • 因此strlen(a) = 128 + 127 = 255

大小端的介绍

  • 首先我们要知道,整数在内存中有两种存储形式:大端字节序存储和小端字节序存储
  • 字节序:是以字节为单位,讨论存储顺序的
  • 大端字节序存储:把一个数据的低位字节的内容,从放在高地址处,一个数据的高位字节的内容,存放在低地址处

  • 小端字节序存储:把一个数据的低位字节的内容,从放在低地址处,一个数据的高位字节的内容,存放在高地址处

  • 例如对于如下代码
#include<stdio.h>
int main()
{
  int num = 0x11223344;
  return 0;
}
  • 我们在内存中可以看到num的存储形式:


    可以看到,这是以大小端字节序存储的(左边是低地址,右边是高地址)

Tips

看完了整数在内存中的存储,不妨再了解了解浮点数在内存中的存储,修炼自己的内功,提高自己的能力。


相关文章
|
21天前
|
存储 C语言
数据在内存中的存储方式
本文介绍了计算机中整数和浮点数的存储方式,包括整数的原码、反码、补码,以及浮点数的IEEE754标准存储格式。同时,探讨了大小端字节序的概念及其判断方法,通过实例代码展示了这些概念的实际应用。
44 1
|
26天前
|
存储
共用体在内存中如何存储数据
共用体(Union)在内存中为所有成员分配同一段内存空间,大小等于最大成员所需的空间。这意味着所有成员共享同一块内存,但同一时间只能存储其中一个成员的数据,无法同时保存多个成员的值。
|
30天前
|
存储 弹性计算 算法
前端大模型应用笔记(四):如何在资源受限例如1核和1G内存的端侧或ECS上运行一个合适的向量存储库及如何优化
本文探讨了在资源受限的嵌入式设备(如1核处理器和1GB内存)上实现高效向量存储和检索的方法,旨在支持端侧大模型应用。文章分析了Annoy、HNSWLib、NMSLib、FLANN、VP-Trees和Lshbox等向量存储库的特点与适用场景,推荐Annoy作为多数情况下的首选方案,并提出了数据预处理、索引优化、查询优化等策略以提升性能。通过这些方法,即使在资源受限的环境中也能实现高效的向量检索。
|
1月前
|
存储 编译器
数据在内存中的存储
数据在内存中的存储
41 4
|
1月前
|
存储 Java
JVM知识体系学习四:排序规范(happens-before原则)、对象创建过程、对象的内存中存储布局、对象的大小、对象头内容、对象如何定位、对象如何分配
这篇文章详细地介绍了Java对象的创建过程、内存布局、对象头的MarkWord、对象的定位方式以及对象的分配策略,并深入探讨了happens-before原则以确保多线程环境下的正确同步。
53 0
JVM知识体系学习四:排序规范(happens-before原则)、对象创建过程、对象的内存中存储布局、对象的大小、对象头内容、对象如何定位、对象如何分配
|
1月前
|
存储 机器学习/深度学习 人工智能
数据在内存中的存储
数据在内存中的存储
|
1月前
|
存储 C语言
深入C语言内存:数据在内存中的存储
深入C语言内存:数据在内存中的存储
|
1月前
|
存储
整型在内存中的存储
本文详细解释了计算机中整型数据的三种二进制表示方法:原码、反码和补码,并展示了如何将正数和负数的原码转换为反码和补码。
38 0
|
3月前
|
存储 监控 Docker
如何限制docker使用的cpu,内存,存储
如何限制docker使用的cpu,内存,存储
|
4月前
|
存储 分布式计算 Hadoop
HadoopCPU、内存、存储限制
【7月更文挑战第13天】
279 14