当前位置: 代码网 > it编程>编程语言>C/C++ > C语言大小端格式举例详解

C语言大小端格式举例详解

2025年12月18日 C/C++ 我要评论
一、什么是大小端格式大小端指的是多字节数据在内存中的存储顺序。1.小端格式 (little endian)低字节存放在低地址高字节存放在高地址像intel x86/x64、arm(默认)使用小端#in

一、什么是大小端格式

大小端指的是多字节数据在内存中的存储顺序。

1.小端格式 (little endian)

  • 低字节存放在低地址
  • 高字节存放在高地址
  • 像intel x86/x64、arm(默认)使用小端
#include <stdio.h>

int main() {
    int num = 0x12345678;  // 十六进制数
    unsigned char *p = (unsigned char *)#
    
    printf("值: 0x%x\n", num);
    printf("内存布局(低地址->高地址):\n");
    
    for(int i = 0; i < sizeof(int); i++) {
        printf("地址 %p: 0x%x\n", p+i, *(p+i));
    }
    
    return 0;
}

在小端机器上输出:

值: 0x12345678
内存布局(低地址->高地址):
地址 0x7ffe...: 0x78  // 最低字节
地址 0x7ffe...: 0x56
地址 0x7ffe...: 0x34
地址 0x7ffe...: 0x12  // 最高字节

2.大端格式 (big endian)

  • 高字节存放在低地址
  • 低字节存放在高地址
  • 像powerpc、网络字节序使用大端
// 假设在大端机器上运行上述代码,输出为:
值: 0x12345678
内存布局(低地址->高地址):
地址 0x7ffe...: 0x12  // 最高字节
地址 0x7ffe...: 0x34
地址 0x7ffe...: 0x56
地址 0x7ffe...: 0x78  // 最低字节

二、如何检测大小端

方法1:使用联合体

#include <stdio.h>

union endiantest {
    int i;
    char c[sizeof(int)];
};

int islittleendian() {
    union endiantest test;
    test.i = 1;
    return test.c[0] == 1;  // 如果最低地址字节是1,则是小端
}

int main() {
    if (islittleendian()) {
        printf("这是小端机器\n");
    } else {
        printf("这是大端机器\n");
    }
    return 0;
}

方法2:使用指针

int islittleendian() {
    int num = 1;
    return *(char *)&num == 1;
}

三、字节序转换函数

网络编程中经常需要转换:

#include <arpa/inet.h>  // linux
// 或 #include <winsock2.h>  // windows

uint32_t htonl(uint32_t hostlong);   // 主机->网络(32位)
uint16_t htons(uint16_t hostshort);  // 主机->网络(16位)
uint32_t ntohl(uint32_t netlong);    // 网络->主机(32位)
uint16_t ntohs(uint16_t netshort);   // 网络->主机(16位)

// 示例:
uint32_t host_value = 0x12345678;
uint32_t network_value = htonl(host_value);  // 转换为网络字节序

四、什么情况下使用哪种格式

使用小端格式的情况:

  1. x86/x64架构的cpu(intel、amd)
  2. arm处理器(默认小端,可切换)
  3. windows/linux桌面系统
  4. 多数嵌入式系统
  5. 本地数据存储(当不需要跨平台时)

优点:

  • 数学运算方便(从低字节开始处理)
  • 类型转换简单

使用大端格式的情况:

  1. 网络协议(tcp/ip规定使用大端)
  2. powerpc架构
  3. 某些旧版sparc、mips系统
  4. java虚拟机内部(大端)
  5. 图像文件格式(如bmp、jpeg)
  6. 某些硬件设备的寄存器

优点:

  • 人类阅读友好(与书写顺序一致)
  • 容易判断数值正负(符号位在最低地址)

五、实际应用示例

示例1:网络数据包解析

#include <stdio.h>
#include <stdint.h>

// 模拟从网络接收的数据(大端格式)
void parsenetworkpacket(const uint8_t *packet) {
    // 前4字节是大端的ip地址
    uint32_t ip = (packet[0] << 24) | 
                  (packet[1] << 16) | 
                  (packet[2] << 8) | 
                  packet[3];
    
    // 使用ntohl转换成本机字节序
    ip = ntohl(*(uint32_t*)packet);  // 更标准的做法
    
    printf("ip地址: %u.%u.%u.%u\n", 
           (ip >> 24) & 0xff,
           (ip >> 16) & 0xff,
           (ip >> 8) & 0xff,
           ip & 0xff);
}

示例2:文件格式处理

// 读取bmp文件头(大端格式)
#pragma pack(push, 1)
typedef struct {
    uint16_t signature;     // "bm",大端
    uint32_t filesize;      // 大端
    uint16_t reserved1;
    uint16_t reserved2;
    uint32_t dataoffset;    // 大端
} bmpheader;
#pragma pack(pop)

void readbmp(const char *filename) {
    file *file = fopen(filename, "rb");
    bmpheader header;
    fread(&header, sizeof(header), 1, file);
    
    // 转换字节序
    header.signature = ntohs(header.signature);
    header.filesize = ntohl(header.filesize);
    header.dataoffset = ntohl(header.dataoffset);
    
    fclose(file);
}

六、编写跨平台代码的建议

  1. 使用标准转换函数(htonl/ntohl等)
  2. 避免直接内存拷贝不同字节序的数据
  3. 明确数据格式在文档中说明
  4. 测试时考虑字节序
  5. 使用固定宽度整数类型(uint8_t, uint32_t等)
// 安全的字节序无关的读取
uint32_t readuint32bigendian(const uint8_t *buffer) {
    return (buffer[0] << 24) | 
           (buffer[1] << 16) | 
           (buffer[2] << 8) | 
           buffer[3];
}

uint32_t readuint32littleendian(const uint8_t *buffer) {
    return buffer[0] | 
           (buffer[1] << 8) | 
           (buffer[2] << 16) | 
           (buffer[3] << 24);
}

总结

  • 小端:低字节在低地址,常见于intel cpu
  • 大端:高字节在低地址,用于网络和某些硬件
  • 网络通信必须使用大端
  • 本地存储通常使用本机字节序
  • 跨平台开发要注意字节序转换

理解大小端对网络编程、文件格式解析、硬件交互等至关重要!

到此这篇关于c语言大小端格式的文章就介绍到这了,更多相关c语言大小端格式内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com