大小端模式

简介: 大小端模式

记录本篇的缘由是在一次面试题中,面试官问起大小端的问题,没有答出来。这里做一份笔记。

主要内容参考这篇博客

定义

大端模式(Big-endian):高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。

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

面试的时候记住一个词就够了,“小高高”,即:小端模式–高字节数据–高地址位置。

字节顺序高低

以一个4字节的整型数值 int a = 0x12345678 为例,该数的十六进制,十进制及二进制分别为:

HEX 12345678

DEC 305,419,896

BIN 0001 0010, 0011 0100, 0101 0110, 0111 1000

那么二进制及十六进制的数位对应关系为:

0001 0010 | 0011 0100| 0101 0110 | 0111 1000 (二进制)

0x12 | 0x34 | 0x56 | 0x78 (十六进制)

高字节 -----------------> 低字节

地址位置高低

同样以这个4字节的整型数值 a = 0x12345678为例,目前不清楚该数值在机器上的存储顺序,但是如果对其分配内存空间,则四个字节的顺序假如是一段0x00010x0004的内存段,那么内存的增长顺序即为低地址到高地址。

0x0001 | 0x0002 | 0x0003 | 0x0004

低地址 ------------------> 高地址

代码验证

采用两种方法检查本机器上的大小端模式。

#include <iostream>
int main()
{
#if 1
    union {
       int ia;
       char ca[4];
    } un;
    un.ca[0] = 0x12;
    un.ca[1] = 0x34;
    un.ca[2] = 0x56;
    un.ca[3] = 0x78;
    printf("0x%x,%d\n",un.ia,sizeof(int));
    if(un.ia == 0x12345678)
        printf("big endien\n");
    else if(un.ia == 0x78563412)
        printf("little endien\n");
#else
    int ia = 0x12345678;
    char *ca = (char*)(&ia);
    printf("0x%x,%d\n",*ca,sizeof(int));
    if(*ca == 0x12)
        printf("big endien\n");
    else if(*ca == 0x78)
        printf("little endien\n");
#endif
    return 0;
}

x86机器上是小端模式。PowerPc机器上是大端模式。网络字节传输采用大端模式。

大小端转换

#include<stdio.h>
typedef unsigned int uint_32 ;
typedef unsigned short uint_16 ;
//16位
#define BSWAP_16(x) \
(uint_16)((((uint_16)(x) & 0x00ff) << 8) | \ (((uint_16)(x) & 0xff00) >> 8) \)
//32位
#define BSWAP_32(x) \
(uint_32)((((uint_32)(x) & 0xff000000) >> 24) | \ (((uint_32)(x) & 0x00ff0000) >> 8) | \
(((uint_32)(x) & 0x0000ff00) << 8) | \ (((uint_32)(x) & 0x000000ff) << 24) \)
//无符号整型16位
uint_16 bswap_16(uint_16 x)
{
  return (((uint_16)(x) & 0x00ff) << 8) | \ (((uint_16)(x) & 0xff00) >> 8) ;
}
//无符号整型32位
uint_32 bswap_32(uint_32 x)
{
  return (((uint_32)(x) & 0xff000000) >> 24) | \ (((uint_32)(x) & 0x00ff0000) >> 8) | \
  (((uint_32)(x) & 0x0000ff00) << 8) | \ (((uint_32)(x) & 0x000000ff) << 24) ;
}
int main(int argc,char *argv[])
{
 printf("------------带参宏-------------\n");
 printf("%#x\n",BSWAP_16(0x1234)) ;
 printf("%#x\n",BSWAP_32(0x12345678));
 printf("------------函数调用-----------\n");
 printf("%#x\n",bswap_16(0x1234)) ;
 printf("%#x\n",bswap_32(0x12345678));
 return 0 ;
}
输出结果:
------------带参宏-------------
0x3412
0x78563412
------------函数调用-----------
0x3412
0x78563412

大小端转换可以采用以上的位操作方式,也可以采用使用 htonl, htons,ntohl,ntohs 等函数实现。读者有需要可自行参考本篇开头放置的博客链接,进行深入了解。

相关文章
|
2月前
|
存储
计算机存储,字节分为大端和小端
计算机存储,字节分为大端和小端
43 1
|
2月前
|
存储 网络协议 API
大端与小端概念、多字节之间与单字节多部分的大小端转换详解
大端与小端概念、多字节之间与单字节多部分的大小端转换详解
178 1
|
2月前
大端法和小端法
大端法和小端法
23 2
|
10月前
|
C语言
关于大小端模式的浅谈
关于大小端模式的浅谈
43 0
|
10月前
|
存储 小程序 编译器
C语言:大小端字节序存储
大端字节序存储模式:把一个数据低位字节处的数据存放在高地址处,数据高位字节处的数据存放在低地址处
69 0
|
11月前
|
存储 编译器 C语言
大小端字节序和整型提升
大小端字节序和整型提升
|
存储 编译器 C语言
【大小端问题】
大小端是什么? 计算机在内存存储中有两中存储模式: 大端字节序存储模式和小端字节序存储模式。 大端存储模式,是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中。 小端存储模式,是指数据的低位保存在内存的低地址中,而数据的高位,保存在内存的高地址中。
|
存储 IDE 编译器
C语言中整形的大小端存储
众所周知,在IDE Visual studio中,调试后可以在内存窗口中看见程序中一些变量的地址以及值 我们这里将一个16进制数字0x12345678存到内存中
59 0
|
存储 C语言
【C语言】大小端字节序问题
一、大小端字节序问题 大小端是由CPU决定的,大小端可以理解为字节顺序,所以大小端全称叫大端字节序、小端字节序。其实大端、小端这两个词是从《格列佛游记》里出来的。《格列佛游记》有一段讲的是吃鸡蛋是从大的那头敲开还是小的那头敲开的问题,书中把从大头敲开的那种叫做大端,把从小头敲开的那种叫小端,第一个指出计算机数据存储顺序问题的人就采用了这个大小端的说法。
|
存储 编译器 C语言