🔥作者简介: 一个平凡而乐于分享的小比特,中南民族大学通信工程专业研究生,研究方向无线联邦学习 🎬擅长领域:驱动开发,嵌入式软件开发,BSP开发 ❄️作者主页:一个平凡而乐于分享的小比特的个人主页 ✨收录专栏:c语言重要知识点总结,本专栏旨在总结C语言学习过程中的易错点,通过调试代码,分析原理,对重要知识点有更清晰的理解 欢迎大家点赞 👍 收藏 ⭐ 加关注哦!💖💖

大小端指的是多字节数据在内存中的存储顺序。
#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 // 最高字节// 假设在大端机器上运行上述代码,输出为:
值: 0x12345678
内存布局(低地址->高地址):
地址 0x7ffe...: 0x12 // 最高字节
地址 0x7ffe...: 0x34
地址 0x7ffe...: 0x56
地址 0x7ffe...: 0x78 // 最低字节#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;
}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); // 转换为网络字节序优点:
优点:
#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);
}// 读取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);
}// 安全的字节序无关的读取
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);
}理解大小端对网络编程、文件格式解析、硬件交互等至关重要!