C语言 大小端 存储

大小端

  刚开始听到这个词,是不是一头雾水?难道数据在计算机中的存储顺序还不一样?大小端是什么鬼?首先,要先知道一个常识,大小端只是不同的硬件中存储的方式不一样,没有对错之分,但各有优缺点。那么说了那么多,什么是大小端呢?

大端

  大端存储模式,是指数据的地位内存保存在内存的高地址中,而数据的高位,保存在内存的低地址中。
  例如一个整数1234,在内存中是怎么储存的呢?以32位为例,首先将其转化成二进制
  十进制:1234
  二进制:100 1101 0010
在这里插入图片描述
  而在我们内存中是有着32个bite位用来存储整型数据,因此,存储应如下所示:
在这里插入图片描述  位数不够时,将高位用0填充,然后将高位的数据存放在低地址总,低位的数据存放在高地址中,即00 00 04 D2

小端

  与大端的存储方式恰恰相反,小端存储模式,是指数据的低位保存在内存的低地址中,而数据的高位,,保存在内存的高地址中。
  同样,我们以1234为例
在这里插入图片描述  那么为什么会出现大小端之分呢?那是因为在计算机系统中,我们对数据的存储都是以字节为单位的,每一个单元地址都对应着一个字节,一个字节对应8个bit位,但是我们对数据的存储可不单单只限于这char型一个字节,还有2字节的short,4字节的int,8字节的long型,另外,对于位数大于8位的处理器,例如16位或者32位的处理器,由于寄存器宽度大于一个字节,那么必然存在着一个如果将多个字节安排的问题。因此就导致了大端存储模式和小端存储模式。
  了解了大小端基本的概念之后,那么我们便要学着怎样辨别一台机器是使用大端呢还是小端,我们用以下这个小小的程序就可以搞定了:

bool check_mode()
{
	int a = 1;
	return (*(char*)&a) == 1;//取a的低地址位如果为1,则是小端模式,反之则为大端
}

void main()
{
	bool flag = check_mode();
	if(flag)
		printf("This is little.\n");
	else
		printf("This is big.\n");
}

  大家在面对程序运算时一定要进行分析,将这种情况考虑进去。
例如:

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

  这个程序的输出结果该是什么呢?难道是9 8 7 6 5 4 3 2 1 0?
  结果往往是出人意料的,它会一直不停的输出,无限的死循环。因为其是无符号数,当它减到0时,再往下减下去将是1111 1111 1111 1111 1111 1111 1111 1111,这是一个多么大的数呀,之后在继续循环,当减为0时,依旧如此,因此是无限循环。

  因此大家对于大小端以及数据的存储可千万不要掉以轻心哦。。。

### C语言中的大小端概念 在计算机科学中,大小端指的是多字节数值在内存中的存储顺序。对于一个多字节的数据类型(如`int`),其高位字节和低位字节可以有两种不同的排列方式: - **大端模式**:最高有效位存放在最低地址处;最低有效位存放在最高地址处。 - **小端模式**:最低有效位存放在最低地址处;最高有效位存放在最高地址处。 这种差异影响着程序读取和写入数据的方式,在跨平台开发时尤其重要[^1]。 ### 判断大小端的方法 为了检测当前系统的字节序,可以通过指针操作来访问整数值的不同部分。下面是一个简单的C语言函数用于区分大小端: ```c #include <stdio.h> void check_endian() { unsigned int num = 0x12345678; char *ptr = (char*)&num; if (*ptr == 0x78) { printf("Little endian\n"); } else if (*ptr == 0x12){ printf("Big endian\n"); } } ``` 上述代码通过创建一个无符号整形变量并将其首地址强制转换成字符指针指向它自己,接着检查第一个字节的内容是否等于给定十六进制数的最后一位(即`0x78`)。如果是,则表示系统采用的是小端格式;反之则是大端格式[^3]。 ### 转换大小端的例子 当需要处理不同架构之间的兼容性问题时,可能还需要能够将一种字节序转为另一种。以下是利用位运算实现的一个简单示例: ```c uint32_t swap_endian(uint32_t value) { return ((value & 0xFF000000) >> 24) | ((value & 0x00FF0000) >> 8 ) | ((value & 0x0000FF00) << 8 ) | ((value & 0x000000FF) << 24); } ``` 此函数接收一个32位无符号整数作为参数,并返回经过交换后的结果。每一步都将原值按特定位置提取出来再移动到新的目标位置上完成整个过程[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值