大小端的判断及转换

    大端模式:是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放;这和我们的阅读习惯一致。
    小端模式:是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中,这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低。
(1)为什么会有大小端之分?

    因为在计算机系统中,是以字节为单位的,每个地址单元都对应着一个字节,一个字节为 8bit. 在C中除了char的8位,short的16位(具体大小多少要看编译器,就像32位和64位系统,所占大小是不一样的),另外对于位数大于8 位的处理器,例如16位或者32位的处理器,由于寄存器宽度大于一个字节,那么必然存在着一个如何将多个字节安排的问题。因此就导致了大端存储模式和小端存储模式。

    例如一个16bit的short x,若在内存中的地址为0x0010,x的值为0x1122,那么0x11为高字节,0x22为低字节。对于大端模式,就将0x11放在低地址中,即0x0010中,0x22放在高地址中,即0x0011中。小端模式,刚好相反。我们常用的X86系统是小端模式。
内存中地址在这种表示法从左往右,由低地址到高地址。

(2)判断大小端

可用共用体判断:

int fun()
{
    union test
    {
    	int a;
    	char ch;
    }a;
    a.a = 1;
    return (a.ch == 1)
}

令a = 1, 即为0x00000001。

然后只要判断a.ch 是否为真,若是则为小端,不是则为大端,因为不管大端小端,存地址都是从首位开始存放。

(3)将整型数据按位逆序

主要想考的就是位运算的使用,就是怎么把一个整数的高低位的数值调用。
即:如果输入1,即0001,应该输出1000,即8。如果输出257,即0010 0101 0111,应该输出0100 1010 1110

#ifndef INTERVIEW_BIG_LITTLE_H
#define INTERVIEW_BIG_LITTLE_H
 
typedef unsigned short int uint16;
typedef unsigned long int uint32;
 
#define swp16(x) \
		(((short)(x) & (short)0x00ff) << 8) | \
		(((short)(x) & (short)0xff00) >> 8)
 
#define Swap32(A) \
		( (((uint32)(A) & (0xff000000)) >> 24) | \
		(((uint32)(A) & (0x00ff0000)) >> 8) | \
		(((uint32)(A) & (0x0000ff00)) << 8) | \
		(((uint32)(A) & (0x000000ff)) << 24) )
 
#endif //INTERVIEW_BIG_LITTLE_H

假设x=0xaabb
那(short)(x) & (short)0x00ff) ,就先将16位数高8位置0,成了0x00bb, 然后<<8 向左移8位后,低8位变成了高8位,低8位补0  结果为 0xbb00,后面一样

(4)按字节逆序

下面用宏实现:

#define Swap16(a) \
        ((((a) & 0xff) << 8) | (((a) >> 8) & 0xff))  


#define Swap32(a) \
           (((a) >> 24) | (((a) & 0x00ff0000) >> 8) | \  
           (((a) & 0x0000ff00) << 8) | ((a) << 24))  


#define Swap64(a) 
        (((a) >> 56) | \  
        (((a) & 0x00ff000000000000) >> 40) | \
        (((a) & 0x0000ff0000000000) >> 24) | \
        (((a) & 0x000000ff00000000) >> 8)  | \
        (((a) & 0x00000000ff000000) << 8)  | \
        (((a) & 0x0000000000ff0000) << 24) | \ 
        (((a) & 0x000000000000ff00) << 40) | \ 
        (((a) << 56)))  

vs2012以上提供ntohs、htons、ntohl、htonl这4个函数,已实现16位和32位本地字节序的大小端转换

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值