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

文章介绍了整数在内存中如何以原码、反码和补码的形式存储,以及如何通过这些编码方式推导出不同整型的最大和最小值。同时,文章还涉及了大小端字节序的概念,帮助理解数据在不同地址空间的组织方式。通过示例题目,强调了整型提升和溢出的效果,展示了char类型的数值循环。
摘要由CSDN通过智能技术生成

整数在内存中的存储

  • 我们知道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的所有位都是数值位,所表示的数只能是非负数

    • 对于二进制、八进制、十六进制及其计算还不太了解的,建议看看二进制、八进制、十六进制与十进制的相互关系

数据类型占字节数整型表示的最大范围
char1-128~127
unsigned char10~2 * CHAR_MAX + 1
short2-32768~32767
unsigned short20~2 * SHRT_MAX + 1
int4-2147483648~2147483647
unsigned int40~2 * INT_MAX + 1
long4/8-2147483648~2147483647 / -9223372036854775808~9223372036854775807
unsigned long4/80~2 * INT_MAX + 1 / 0~2 * LLONG_MAX + 1
long long8-9223372036854775808~9223372036854775807
unsigned long long80~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

大小端的介绍

  • 首先我们要知道,整数在内存中有两种存储形式:大端字节序存储和小端字节序存储

    • 字节序:是以字节为单位,讨论存储顺序的

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

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4wtCSgxG-1685285880695)(C:/Users/HUASHUO/AppData/Roaming/Typora/typora-user-images/image-20230527173833546.png)]

    • 小端字节序存储:把一个数据的低位字节的内容,从放在低地址处,一个数据的高位字节的内容,存放在高地址处
      在这里插入图片描述

  • 例如对于如下代码

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

    在这里插入图片描述

    在这里插入图片描述

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

Tips

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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Forward♞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值