(C语言)整数在内存中的存储与大小端

1. 整数在内存中的存储

整数的2进制表示方法有三种 ,即 原码、反码和补码

有符号类型数据三种表示方法均有符号位和数值位两部分 ,符号位都是用0表示“正” ,用1表示“负” ,最高位的一位是被当做符号位 ,剩余的都是数值位。

无符号类型的数据没有符号位只能表示正数。

正整数的原、反、补码都相同。

负整数的三种表示方法各不相同。

原码:直接将数值按照正负数的形式翻译成二进制得到的就是原码。

反码:将原码的符号位不变 ,其他位依次按位取反就可以得到反码。

补码:反码+1就得到补码。

对于整形来说:数据存放内存中其实存放的是补码

为什么呢?

在计算机系统中 ,数值一律用补码来表示和存储。原因在于 ,使用补码 ,可以将符号位和数值域统一处理;同时 ,加法和减法也可以统一处理(CPU只有加法器) 此外 ,补码与原码相互转换 ,其运算过程是相同的 ,不需要额外的硬件电路。

2. 大小端字节序和字节序

我们来看一下数据在在内存中具体是怎么存在的:

我们发现16进制的11223344在内存中是以字节为单位倒着存储的。为什么呢?

2.1 什么是大小端

其实超过一个字节的数据在内存中存储的时候 ,就有存储顺序的问题 ,按照不同的存储顺序 ,我们分为大端字节序存储和小端字节序存储 ,下面是具体的概念:

大端(存储)模式:是指数据的低位字节内容保存在内存的高地址处 ,而数据的高位字节内容 ,保存在内存的低地址处。

小端(存储)模式:是指数据的低位字节内容保存在内存的低地址处 ,而数据的高位字节内容 ,保存在内存的高地址处。

2.2 为什么有大小端?

这是因为在计算机系统中 ,我们是以字节为单位的 ,每个地址单元都对应着一个字节 ,一个字节为8 bit 位 ,但是在C语言中除了8 bit 的char之外,还有16bit的short型,32bit的long型(要看具体的编译器),另外 ,对于位数大于8位的处理器 ,例如16位或者32位的处理器  于寄存器宽度大 于一个字节 ,那么必然存在着一个如何将多个字节安排的问题。 因此就导致了大端存储模式和小端存储模式。

例如:一个16bit的short型x,在内存中的地址为0x0010,x的值为0x1122,那么0x11为高字节,0x22为低字节,对于大端模式,就将0x11放在低地址中,及0x0010中,0x22放在高地址中,及0x0011中;小端模式,和其相反,我们常用的x86结构是小端模式,而KETL C51则为大端模式,很多ARM,DSP都为小端模式,有些ARM处理器还可以由硬件来选择是大端模式还是小端模式。

2.2 设计程序验证大小端

我们来设计一个程序来看看我们的编译器是什么模式

#include <stdio.h>

int Check()
{
	int i = 1;
	char* p = &i;
	return *p;
	//大端模式下返回0
	//小端模式下返回1
}

int main()
{
	if (Check())
		printf("小端模式");
	else
		printf("大端模式");
	return 0;
}

我在vs2022下运行结果为:小端模式

练习题

我们再来看一道练习题

#include <stdio.h>

int main()
{
	int a[4] = { 1, 2, 3, 4 };
	int* ptr1 = (int*)(&a + 1);
	int* ptr2 = (int*)((int)a + 1);
	printf("%x,%x", ptr1[-1], *ptr2);
	return 0;

}

这道题的输出结果是什么,先想一想。

解析:先看ptr1,&a+1指针跳过整个数组,然后有强制类型转换为int*,ptr1[-1]等于*(ptr-1),ptr-1,指向数组中的4,然后解引用结果为4,

再看ptr2,a为数组的首元素地址,将其强制类型转换为int再+1,即为地址这个数字加了1,再强制类型转换换位int*及指针指向了数组元素1中的第二个字节,然后再解引用,向后访问四个字节,因为我的编译器是小端模式,1在内存中是0x01000000 .2在内存中是这样的0x04000000,ptr2解引用访问到元素1中的0x000000和元素2中的0x02即返回0x02000000,以16进制打印结果为2000000

故答案为 4,2000000

感谢观看,欢迎在评论区讨论。

  • 37
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值