C中大端小端的问题

来源:互联网 发布:java记录日志的方式 编辑:程序博客网 时间:2024/06/05 09:53

   最近在牛客网经常遇到大端小端的问题,之前学嵌入式时51单片机也经常涉及大端小端模式的存储问题。以下是自己的理解和摘自牛客网的东西。

大端模式(Big- endian,就是数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中,这种存储模式和字符串的顺序处理类似(也可以这么记):地址由小向大增加,而数据从高位往低位放;    

小端模式(Little-endian,是指数据的低位保存在内存的低地址中,而数据的高位保存在内存的高地址中,这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低,和正常的逻辑思维一致。

一句话:采用Little-endian模式的CPU对操作数的存放方式是从低字节到高字节,而Big-endian模式对操作数的存放方式是从高字节到低字节。

以下是牛客网的表格解析示例:

例如,16bit宽的数0x1234在Little-endian模式CPU内存中的存放方式(假设从地址0x4000开始存 放)为: 

内存地址

存放内容

0x4000

0x34

0x4001

0x12

而在Big-endian模式CPU内存中的存放方式则为: 

内存地址

存放内容

0x4000

0x12

0x4001

0x34

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

内存地址

存放内容

0x4000

0x78

0x4001

0x56

0x4002

0x34

0x4003

0x12

而在Big-endian模式CPU内存中的存放方式则为: 

内存地址

存放内容

0x4000

0x12

0x4001

0x34

0x4002

0x56

0x4003

0x78


我们可以用联合体union来检测CPU是大端还是小端存放。union中可以定义多个成员,但union的大小由最大的成员的大小决定。所以union成员共享同一块大小的内存(最大的成员,且要字节对齐!),且union 的存放顺序是所有成员都从低地址开始存放。

比如:

union{   int a;  char str[13];}u;

sizeof(u)=16 .因为这里最大的是字符数组,但单个变量最大是int,它需要4字节对齐,所以字符数组需要取4的整补齐,就是16字节。

利用union的这些特性,编写如下函数,可以检测出到底是大端还是小端。

若处理器是Big_endian的,则返回0;若是Little_endian的,则返回1

int checkCPU(){ { union w { int a; char b; } c; c.a = 1; return (c.b == 1); }}
这是简单的函数写法,你也可以直接

<span style="font-size:14px;">union{   unsigned short int data;   char  c[1];} data =0x1234; c[0]=12 ? c[0]=34 ? //看大端还是小端</span>





2 0
原创粉丝点击