文章目录

  • 1、字符表示(编码)
  • 2、什么是字节序
  • 3、大小端模式的区别
    • 举个例子
    • 如何 C 编程判断CPU是大端还是小端模式
    • 例题一
    • 例题二:大端模式向小端模式发送数据
  • 4、字节序转换函数

核心就是:一个是数据字节顺序,一个内存存储地址顺序

为什么会有 大端模式小端模式的区别的,这是由于编码的原因,因此,先大致介绍一下编码:


1、字符表示(编码)

在之前的计算机中,一般都是用 ASCII 码,但是其只能表示 2^7 = 128 个不同的字符。(仅仅只能表示 英文)

随着计算机的发展,计算机要表示不同国家的文字,比如 中文、泰文等等。那么这个时候,ASCII 编码就完全不够用了。

所以,引入了 Unicode编码,其目的就是:把世界上的文字都映射到一套字符空间中

为了表示Unicode字符集,有下面 3 种(确切的说是 5 种)Unicode的编码方式

  1. UTF-8:很常用的一种。其中 8 表示 8bits,也就是用 1 byte 来表示字符。可以兼容 ASCII码;其特点是:

    • 存储效率高
    • 变长;这是因为, 1 byte 最多也只能 2^8 = 256 个字符,明显不够,所以可以多个 UTF-8 来表示一个字符,可组合。所以其 长度可以不是 1 byte,是可以改变的。但这也导致了,在内部访问的时候,由于不知道具体长度,所以很不方便。
    • 无字节序问题;字节序问题就是,大小端模式的不同。因为 UTF-8 只有 1 byte,对于地址而言,一个字节就存在一个地址上,那么就不会出现字节序问题。
  2. UTF-16,其又会具体分为:UTF-16BE (big endian)和UTF-16LE (little endian)。其特点为:
    • 定长;因为用了 16 bit,也就是 2 byte 来表示,占用字节长度是固定的。方便内部随机访问。
    • 存在字节序问题;这样子对外部而言,也就是其他机器而言(因为不同机器的字节序会不同),那么到其他机器
  3. UTF-32,其又会具体分为:UTF-32BE (big endian)和UTF-32LE (little endian)。
    • 这个是在 UTF-16 的基础上,又增加了一个字符的字节表示数。即一个字符,用 32 bit 即 4 byte 来表示。

对于不同的编码,当一个文本文件,用 二进制形式打开的时候,最前面的几个字节就可以区分是什么编码

编码错误的根本原因,在于编码方式和解码方式的不统一,也就是说,当一个机器用的是这种编码方式。到这个文件到了另一个机器时,如果另一个机器用的解码方式对不上,就会导致显示乱码

一般的编程语言,没有声明其 编码方式。而 html 会在一开始声明其 编码方式,这样子方便其他机器知道编码方式后,用对应的解码来处理。所以 html 才用于 网页的设计,因为会在不同机器上传输。


2、什么是字节序

字节序问题,就是,当我们一个东西,用多个 byte 表示的时候。

又因为内存地址,一个地址只表示 1 byte。

所以,对于内存地址而言,地址一般是从 低地址到高地址的。

而,对于多个 byte 表示的那个东西,也会有所谓的字节顺序。举个例子,0x12345678,这是由 4 byte 表示的一个数(也可以是一个字符之类的),那么一般其 字节序就是,高到低为:12 34 56 78(十六进制表示,2位就是 8 bit,即 1 byte)

那么对于,字节表示的内容,当存放在 地址的时候,就会有两种顺序,我们假设内存地址都是 低地址到高地址。同样的,还是 0x12345678,此时有两种情况

情况一:

此时,对于 高位字节位置 对应在 低地址。这和我们直接读的时候,很符合(称为 大端模式 – 低地址对应高字节位置

这个读的时候,由于低地址对应高字节,而我们平时都是高字节读起,所以其存储习惯符合我们直接读取:0x 12 34 56 78 = 0x12345678

   低地址                                            高地址----------------------------------------------------------------------------->|     12     |      34    |     56      |     78    |

情况二:

此时,对于 高字节位置,对应在高地址。也就是说,低地址 对应 低字节位置,称为 小端模式。这个时候读字节结果的时候,需要从 高字节到低字节,即 高地址到低地址:0x 12 34 56 78 = 0x12345678

   低地址                                            高地址----------------------------------------------------------------------------->|     78     |      56    |     34      |     12    |

3、大小端模式的区别

上面也大概介绍了一下 字节序的问题。

一般字节序的问题,是由于系统自身存储的问题,一般分为两大 CPU派系:那就是Motorola的PowerPC系列CPU和Intel的x86系列CPU。PowerPC系列采用big endian方式存储数据,而x86系列则采用little endian方式存储数据。

big endian是指低地址存放最高有效字节(MSB)

little endian则是低地址存放最低有效字节(LSB)

记忆方式:内存地址,永远都是从 低地址开始的
大端模式:低地址 对应 高字节(大 – 高字节)
小端模式:低地址 对应 低字节(小 – 低字节)

举个例子

数字0x12345678在两种不同字节序CPU中的存储顺序如下所示

大端模式

此时,对于 高位字节位置 对应在 低地址。这和我们直接读的时候,很符合(称为 大端模式 – 低地址对应高字节位置

这个读的时候,由于低地址对应高字节,而我们平时都是高字节读起,所以其存储习惯符合我们直接读取:0x 12 34 56 78 = 0x12345678

   低地址                                            高地址----------------------------------------------------------------------------->|     12     |      34    |     56      |     78    |

小端模式

此时,对于 高字节位置,对应在高地址。也就是说,低地址 对应 低字节位置,称为 小端模式。这个时候读字节结果的时候,需要从 高字节到低字节,即 高地址到低地址:0x 12 34 56 78 = 0x12345678

   低地址                                            高地址----------------------------------------------------------------------------->|     78     |      56    |     34      |     12    |

C/C++ 语言编写的程序里数据存储顺序是跟编译平台所在的CPU相关的,而JAVA编写的程序则唯一采用big endian方式来存储数据。
试想,如果你用C/C++ 语言在x86平台下编写的程序跟别人的JAVA程序互通时会产生什么结果?就拿上面的0x12345678来说,你的程序传递给别人的一个数据,将指向0x12345678的指针传给了JAVA程序,由于JAVA采取big endian方式存储数据,很自然的它会将你的数据翻译为0x78563412。因此,在你的C程序传给JAVA程序之前有必要进行字节序的转换工作。

所有网络协议也都是采用big endian的方式来传输数据的。所以有时我们也会把big endian方式称之为网络字节序。当两台采用不同字节序的主机通信时,在发送数据之前都必须经过字节序的转换成为网络字节序后再进行传输。

如何 C 编程判断CPU是大端还是小端模式

// 若处理器是Big_endian的,则返回0;若是Little_endian的,则返回1。
// 解释:union 是共用体,即里面的所有数据是共用同一块内存空间的,由占据字节最大的绝对
// 这个里面有 int 和 char,int 是 4 字节,char 是 1 字节。所以 union w 总共占据 4 字节的内存
// 我们将 c.a = 1,那么根据 int 的,那么 a 的值为 0x 00 00 00 01
// 假设顺序是 低地址到高地址
// 如果是 00 00 00 01 的存,那就是,低地址对应高字节,大端模式,那么此时对于 char b 而言,只占据 1 字节,所以 b = 0x00,所以 b = 0 为 大端模式
// 如果是 01 00 00 00 的存,那就是,低地址对应低字节,小端模式,那么此时对于 b = 0x01,即 b = 1 为小端模式
// 所以 return (c.b == 1); 当 返回 1(真),就是小端模式;返回 0,为 大端模式int checkCPU()
{{union w{int a;char b;} c;c.a = 1;return (c.b == 1);}
}

例题一

请问下列代码的输出结果有可能是哪些()?

#include<stdint.h>
#include<stdio.h>
union X
{int32_t a;struct {int16_t b;int16_t c;};
};
int main(){X x;x.a=0x20150810;printf("%x,%x\n",x.b,x.c);return 0;
}

A. 2015,810
B. 50810,201
C. 810,2015
D. 20150,810

解析

首先先根据 union 的定义,是由其中最大的字节占用据欸的那个 union 占用的内存空间

union X
{int32_t a; // 那就是 32 bit,也就是 4 字节// struct 是里面的字节占用空间之和(还有其偏移),这个总共占据 4 字节struct {int16_t b;int16_t c;};
};
// 所以 union 总共占据 4 字节

那么当 a = 0x20150810,根据大端和小端的情况,有两种可能:

当是大端时,假设都是从低地址到高地址,那么此时是,低地址对应高字节,那么 20 15 08 10,而 b 和 c 来分这个 4 字节,一人两个字节,那么此时 b 为 20 15,注意此时是 低地址对高字节,所以 b = 0x2015;同理 c = 0x0810

当是小端时,低地址对应低字节,那么此时 a 存储在 内存地址上的为 10 08 15 20,那么分配给 b 和 c,此时 b 为 10 08,而低地址对应低字节

答案

A、C

例题二:大端模式向小端模式发送数据

假设 A 给 B 发送数据,其中 A 是 大端模式,B是 小端模式

此时,A中的数据是 0x12345678

因为 A 是 大端模式,那么就是,低地址对应高字节,即 12 34 56 78,此时,发送给 B(从 A 发给 B,从低地址发,B 也从低地址收),那么 B 接收到的为 12 34 56 78

但是,B 是小端模式,即 低地址对应低字节,那么 B 收到的数据为 0x78563412


4、字节序转换函数

主机字节序一般都是小端(绝大多数,少部分也是大端存储的),网络字节序是大端存储的。

因此,对于从 主机中,发送给另一个主机,一般先将该主机的变为 网络字节序,然后另一个主机接收到 网络字节序后,再转换为 自己的字节序

#include <arpa/inet.h>1.htons():把unsigned short类型从主机序转换到网络序(h:host,主机;n:net,网络;s:unsigned short,16位短整数)
2.htonl():把unsigned long类型从主机序转换到网络序(l:unsigned long,32位长整数)
3.ntohs():把unsigned short类型从网络序转换到主机序
4.ntohl():把unsigned long类型从网络序转换到主机序如果主机序是小端字节序,这些函数将参数做相应的大小端转换然后返回,如果主机序是大端字节序,这些函数将不对参数做转换,将参数原封不动地返回。5.uint32_t htonl(uint32_t hostint32);
功能:将32位主机字节序数据转换为网络字节序数据
参数:hostint32,需要转换的32位主机字节序数据,uint32_t为32位无符号整型
返回值:若成功,返回网络字节序的值6.uint16_t htons(uint16_t hostint16);
功能:将16位主机字节序数据转换成网络字节序数据
参数:hostint16,需要转换的16位主机字节序数据,uint16_t为16为无符号短整型
返回值:若成功,返回网络字节序的值7.uint32_t ntohl(uint32_t netint32);
功能:将32位网络字节序数据转换为主机字节序数据
参数:netint32,需要转换的32位网络字节序数据,uint32_t为32位无符号整型
返回值:若成功,返回主机字节序的值8.uint16_t ntohs(uint16_t netint16);
功能:将16位网络字节序数据转换成主机字节序数据
参数:netint16,需要转换的16位网络字节序数据,uint16_t为16为无符号短整型
返回值:若成功,返回主机字节序的值

Big Endian(大端)和 Little Endian(小端)模式相关推荐

  1. 大端模式 vs 小端模式

    大端模式 VS 小端模式 一:大小端之分的由来 二:内容 代码解析: 方法一: 方法二: 一:大小端之分的由来 这是因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为8 ...

  2. 大端模式(big endian)和小端模式(little endian)

    大端模式 所谓的大端模式(big endian),是指数据的低位(就是权值较小的后面那几位)保存在内存的高地址中,而数据的高位,保存在内存的低地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理 ...

  3. java 大端字节序_理解字节序 大端字节序和小端字节序

    以下内容参考了 http://www.ruanyifeng.com/blog/2016/11/byte-order.html https://blog.csdn.net/yishengzhiai005 ...

  4. C/C++之大端模式和小端模式

    Byte Endian是指字节在内存中的组织,所以也称它为Byte Ordering或Byte Order.对于数据中跨越多个字节的对象, 我们必须为它建立这样的约定: (1) 它的地址是多少? (2 ...

  5. 大端模式小端模式 主机序网络序

    1. 主机序 不同的CPU有不同的字节序类型这些字节序是指整数在内存中保存的顺序,这个叫做主机序.最常见的有两种: 1.         Little endian:将低序字节存储在起始地址. 即小端 ...

  6. 大端模式小端模式、主机序网络序、入栈地址高低问题

    一.大端模式&小端模式 所谓的"大端模式",是指数据的低位(就是权值较小的后面那几位)保存在内存的高地址中,而数据的高位,保存在内存的低地址中,这样的存储模式有点儿类似于把 ...

  7. C语言高级编程:大端模式和小端模式(Big-Endian和Little-Endian)

    大端模式(Big_endian):字数据的高字节存储在低地址中,而字数据的低字节则存放在高地址中. 小端模式(Little_endian):字数据的高字节存储在高地址中,而字数据的低字节则存放在低地址 ...

  8. 【转】理解字节序 大端字节序和小端字节序

    转自:https://www.cnblogs.com/gremount/p/8830707.html 以下内容参考了 http://www.ruanyifeng.com/blog/2016/11/by ...

  9. 大端小端模式判断以及数据转换

    简介 在计算机系统中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为 8bit.但是在C语言中除了8bit的char之外,还有16bit的short型,32bit的long型(要看具体 ...

  10. 大端模式与小端模式的详解分析

    大端序与小端序 何为大端序,小端序? 简单点说,就是字节的存储顺序,如果数据都是单字节的,那怎么存储无所谓了,但是对于多字节数据,比如int,double等,就要考虑存储的顺序了.注意字节序是硬件层面 ...

最新文章

  1. 熟悉常用的HBase操作,编写MapReduce作业
  2. Spring Cloud【Finchley】实战-03订单微服务与商品微服务之间的调用
  3. mysql isam cache_Mysql性能优化基础篇
  4. 提交不了_从来没有借过钱!征信空白,为什么办不了信用卡?
  5. oracle rac ora 12560,rac ORA-12541: TNS:no listener问题 非常急!!
  6. mysql query sql_sql:query 标签
  7. MySQL-03:数据表操作基本命令笔记
  8. mysql fulltext 分页_关于MySQL的FULLTEXT实现全文检索的注意事项
  9. 强上阿里云之安装MYSQL
  10. swoole php input,介绍swoole异步群发模板消息
  11. 统计分组的原则是要体现什么_跨境选品有哪些方法,要遵循什么原则?
  12. 软路由VS高性能路由,该怎么选择?
  13. Mstsc、Telnet、SSH之间的区别
  14. 周华健,歌声伴我成长(五)
  15. schema自动生成前端代码
  16. linux 网桥代码分析之网桥端口设备接收数据包处理分析Ⅴ
  17. 读《当下的力量》有感
  18. 皮亚诺的数概念起点和算术公理1-2告诉我们什么?—— 皮亚诺读后之四
  19. Approximation of functions in fractional Sobolev spaces
  20. OpenCV中的图像基本操作--B站视频教程笔记(四)

热门文章

  1. Adobe有些软件出现“遇到问题需要关闭”问题的解决办法
  2. skydrive云存储+android开放源码,SkyDrive无限云存储
  3. DefaultTableModel
  4. Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|0.0.0.0|:443... failed
  5. 华为OD题目: 相同数字的积木游戏1
  6. stata手动绘制logistic回归预测模型校准曲线(Calibration curve)校准曲线(1)
  7. “小熊电器”IPO获批,其后或再难有小家电企业上市
  8. Opencv学习笔记 离散傅立叶变换(DFT)简介及用于图片方向校正
  9. DW软件如何使用一串特殊代码让你的导航多种角度旋转
  10. recreate()、finish()与onBackPressed()