大小端模式转换

您所在的位置:网站首页 uint32转换成char 大小端模式转换

大小端模式转换

2023-04-02 11:43| 来源: 网络整理| 查看: 265

嗨喽,大家好,我是程序猿老王,程序老王就是我。

今天给大家讲一讲工作中经常遇到的大小端模式转换问题。

首先先来了解一下为什么会存在大小端模式转换

是因为在计算机中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为 8 bit。但是在C 语言中除了 8 bit 的char之外,还有 16 bit 的 short型,32bit的long型(要看具体的编译器),另外,对于位数大于8位的处理器,例如16位或者32位的处理器,由于寄存器宽度大于一个字节,那么必然存在着一个如果将多个字节安排的问题。因此就导致了大端存储模式和小端存储模式。例如一个16bit的short型 x ,在内存中的地址为 0x0010,x 的值为0x1122,那么0x11位高字节,0x22位低字节。对于大端模式,就将0x11放在低地址中,即0x0010中,0x22放在高地址中,即0x0011中。小端模式,刚好相反。我们常用的X86结构是小端模式,而KEIL C51则为大端模式。很多的ARM,DSP都为小端模式。

大小端定义

不同机器内部对变量的字节存储顺序不同,有的采用大端模式(big-endian),有的采用小端模式(little-endian)。

大端模式是指高字节数据存放在低地址处,低字节数据放在高地址处。

小端模式是指低字节数据存放在低地址处,高字节数据放在高地址处。

下面给大家看一个示例就知道了什么是大小端了:

0x12345678在小端模式内存中的表示形式:

 内存 低地址 -----------------> 高地址    0x78 | 0x56 | 0x34 | 0x12    低字节 -----------------> 高字节

0x12345678在大端模式内存中的表示形式:

 内存 低地址 -----------------> 高地址      0x12 | 0x34 | 0x56 | 0x78    高字节 -----------------> 低字节

大小端模式转换方法

在网络上传输数据时,由于数据传输的两端可能对应不同的硬件平台,采用的存储字节顺序也可能不一致,因此 TCP/IP 协议规定了在网络上必须采用网络字节顺序(也就是大端模式) 。

通过对大小端的存储原理分析可发现,对于 char 型数据,由于其只占一个字节,所以不存在这个问题,这也是一般情况下把数据缓冲区定义成 char 类型 的原因之一。对于 IP 地址、端口号等非 char 型数据,必须在数据发送到网络上之前将其转换成大端模式,在接收到数据之后再将其转换成符合接收端主机的存储模式。

Linux 系统为大小端模式的转换提供了 4 个函数,函数原型:

#include uint32_t htonl(uint32_t hostlong); uint16_t htons(uint16_t hostshort); uint32_t ntohl(uint32_t netlong); uint16_t ntohs(uint16_t netshort); htonl 表示 host to network long,用于将主机 unsigned int 型数据转换成网络字节顺序; htons 表示 host to network short,用于将主机 unsigned short 型数据转换成网络字节顺序; ntohl、ntohs 的功能分别与 htonl、htons 相反。

最后再给大家展示一下模拟实现大小端转换函数

typedef unsigned short int uint16; typedef unsigned long int uint32; /*短整型大小端互换*/ #define BigLittleSwap16(A) ((((uint16)(A) & 0xff00) >> 8) | \ (((uint16)(A) & 0x00ff) > 24) | \ (((uint32)(A) & 0x00ff0000) >> 8) | \ (((uint32)(A) & 0x0000ff00)


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3