大小端的小记
大小端虽然是C语言编程中基础的基础,但是不留神考虑,就会带来问题。此文铭记我为大小端的一小时煎熬。
大端叫作:Big Endian
小端叫作:Little Endian
字面意思就是尾端是作为整个变量的最高八位还是最低八位
x86架构下,无论是栈分配或者是堆分配,低地址是作为"尾端",高地址是作为"头端"。
举例如下:
#include <stdio.h> #include <stdlib.h> int main() { char* ptr; int data = 0x10203040; ptr = (char*)&data; printf("%p:%x\n", &data, data); printf("%p:%x %p:%x %p:%x %p:%x\n",&ptr[0],ptr[0],&ptr[1],ptr[1],&ptr[2],ptr[2],&ptr[3],ptr[3]); char* mptr; int* mdata = (int*)malloc(sizeof(int)); *mdata = 0x10203040; mptr = (char*)mdata; printf("%p:%x\n", mdata, *mdata); printf("%p:%x %p:%x %p:%x %p:%x\n",&mptr[0],mptr[0],&mptr[1],mptr[1],&mptr[2],mptr[2],&mptr[3],mptr[3]); return 0; }
打印如下:
0xbf988320:10203040 0xbf988320:40 0xbf988321:30 0xbf988322:20 0xbf988323:10 0x9b72008:10203040 0x9b72008:40 0x9b72009:30 0x9b7200a:20 0x9b7200b:10
特别是在char数组转换到指定类型的时候极容易忽视大小端的问题。导致莫名其妙的错误。
另外网络编程中的函数:htonl,htons,ntohl,ntohs,针对于小端系统,大端系统调用这些函数没有任何效果,因此对于大端系统希望通过这几个函数来做大小端转换的是不可能的。