【C语言】大小端

文章目录

    • 一、什么是大小端?
    • 二、为什么会有大小端存储?
    • 三、如何判断机器的字节序?

一、什么是大小端?

大小端是指计算机中数据的字节序,即数据在内存中的存放顺序

大小端主要有两种类型:大端和小端。(以数字0x12345678在内存中的表示形式为例)

(1)大端模式高位字节排放在内存的低地址端,低位字节排放在内存的高地址

​ 低地址—————>高地址

​ 0x12 | 0x34 | 0x56 | 0x78

(2)小端模式低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。

​ 低地址—————>高地址

​ 0x78 | 0x56 | 0x34 | 0x12

  • 高位字节与低位字节

    对于十进制数 123 123 123,他的最高有效位就是百位 1 1 1,最低有效位是个位 3 3 3。计算机内存一个字节可以存放8个二进制位,最低有效位表示 2 0 = 1 2^0=1 20=1,倒数第二个有效位表示 2 1 = 2 2^1=2 21=2,倒数第三个有效位表示 2 2 = 4 2^2=4 22=4,以此类推。一个多字节数据类型的二进制表示中,将存放最低的8位有效位的字节被称为最低有效位字节或低位字节,而存放最高的8位有效位的字节被称为最高有效位字节或高位字节。

    假如有一个32位整型变量的二进制表示为:

    01010101 11110000 00001111 11000000
    

    其中,最右边的字节为最低有效位字节,也就是低位字节最左边的位为最高有效位字节,也就是高位字节。该变量的高位是01010101,低位是11000000。对于十六进制数字0x12345678,高位是0x12,低位是0x78

  • 高地址与低地址

    计算机中所有的数据都必须放在内存中,不同类型的数据占用的字节数不一样,例如 int 占用4个字节,char 占用1个字节。 为了正确地访问这些数据,必须为每个字节都编上号码,就像门牌号、身份证号一样,每个字节的编号是唯一的,根据编号可以准确地找到某个字节。我们将内存中字节的编号称为 地址(Address) 或 指针(Pointer) 。 地址从 0 开始依次增加,对于 32 位环境,程序能够使用的内存为 4GB,最小的地址为 0x00000000,最大的地址为 0xFFFFFFFF。其中,编号较大的地址称为高地址,编号较小的地址称为低地址

例:32bit宽的数0x12345678在CPU内存中的存放方式(假设从地址0x4000开始存放)为:

内存地址 大端模式 小端模式
0x4000 0x12 0x78
0x4001 0x34 0x56
0x4002 0x56 0x34
0x4003 0x78 0x12

二、为什么会有大小端存储?

原因:

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

各自优势:

  • 小端模式强制转换数据不需要调整字节内容,1、2、4字节的存储方式一样。
  • 大端模式:符号位的判定固定为第一个字节,容易判断正负

三、如何判断机器的字节序?

方法一(指针测试):

#include 
int main() {
    int a = 1;
    char* p = (char*)&a;
    //注:机器读取数据永远是从低地址开始
    //所以此时*p取出的就是第一个字节的数据  -----  低地址的数据
    if (*p == 1) {
        printf("小端模式\n");
    }
    else {
        printf("大端模式\n");
    }
    return 0;
}

方法二(共用体测试):

#include 
union myunion {
	int a;
	char b;
};
int main() {
	union myunion u;
	u.a = 1;
	if (u.b == 1) {
		printf("小端模式\n");
	}
	else {
		printf("大端模式\n");
	}
	return 0;
}

你可能感兴趣的:(c语言,学习,笔记)