首页 > 其他分享 >大小端存储是什么鬼?

大小端存储是什么鬼?

时间:2022-09-04 21:58:18浏览次数:78  
标签:src 存储 字节 什么 传输 地址 大小 数据

以下内容为本人的著作,如需要转载,请声明原文链接 微信公众号「englyf」https://www.cnblogs.com/englyf/p/16656222.html


大小端存储的划分是为了解决长度大于一个字节的数据类型内容在存储地址上以不同顺序分布的问题。

比如16位的short整形,32位的int整形,64位的long整形,它们在存储地址上,其实最小的划分单位是字节,那么高低位的字节排列在从低到高的存储地址上有什么规定呢?

如果最高位的字节数据存在最低地址上,而次高位的字节数据按次序排列在次低的地址上,那么这种存储方式就叫大端存储

如果最低位的字节数据存在最低地址上,而次低位的字节数据按次序排列在次低的地址上,那么这种存储方式就叫小端存储

那么怎么去判断当前系统属于大端存储还是小端存储呢?

判断方法一:利用单字节类型强制转换多字节类型变量获取返回值比较

下面让我们看看实例代码:

#include <iostream>

using namespace std;

bool IsSystemBigEndianStorage()
{
    short src = 1;
    char comp = (char)src;

    return (comp == 0);
}

int main()
{
    bool ret = IsSystemBigEndianStorage();
    if (ret) {
        cout << "big endian" << endl;
    } else {
        cout << "small endian" << endl;
    }

    return 0;
}

首先把单字节范围内的数据值(比如1)赋给更大长度的类型(比如2个字节的short)变量src,然后利用单字节长度的数据类型(char)强制转换变量src,会在内存空间上截取变量src对应存储在最低地址的一个字节数据并返回。

bool IsSystemBigEndianStorage()
{
    short src = 1;
    char comp = (char)src;

    return (comp == 0);
}

可以看到变量src的高位字节数据为0,低位字节数据为1,各不相同。

如果(char)src的返回值等于0,就表示存储在最低地址的字节数据等于高位字节数据0x00,属于大端存储,否则表示属于小端存储

判断方法二:利用联合体类型union比较内部的单字节数据

修改一下上面的函数IsSystemBigEndianStorage

bool IsSystemBigEndianStorage()
{
    union {
        short a;
        char b;
    } temp;
    temp.a = 1;

    return (temp.b == 0);
}

可以看到变量temp.a的高位字节数据为0,低位字节数据为1,各不相同。

根据内存空间中字节对齐的规律,联合体union类型,各成员变量的起始地址是一样的。即使各成员变量的数据长度不一样也不影响。

也就是说temp.a最低地址空间的数据内容就是temp.b的数据内容。

如果temp.b的值等于0,就表示存储在最低地址的字节数据等于高位字节数据0x00,属于大端存储,否则表示属于小端存储

关于网络字节顺序

网络中充斥着各种各样的终端设备或者中间代理路由等,数据利用网络进行传输,传输的基本数据单位也是字节,于是多字节类型的数据也会面临大小端的传输顺序定义。

所以,在传输前和传输后的设备怎么同步这个多字节类型数据的存储呢?由传输前后端的设备共同决定吗?

比如两个不同地区的人碰到一起,如果没有约定俗成的共同语言,一样不知如何去交流。

在数据成功传送和解读完整前,数据两端的设备不会理解对方的意图,那么就有必要由第三方来统一明确定义传输顺序。

于是,TCP/IP 协议规定了网络传输多字节类型数据时,先传输高位的字节数据,次高位的字节数据在其后接着传输。而数据在被网络接口发送到网络时,需要从内存逐字节读取出来,从低地址往高地址开始发送。那么可见在网络传输中,数据的字节顺序形式是大端存储。

本地数据怎么和网络字节顺序转换?

下面针对本地系统为linux举个例子

从本地系统存储顺序转换为网络字节顺序

uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);

从网络字节顺序转换为本地系统存储顺序

uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);

标签:src,存储,字节,什么,传输,地址,大小,数据
From: https://www.cnblogs.com/englyf/p/16656222.html

相关文章

  • 1.try-except 2. if 0<=score<=1.0 3. print加引号是为什么
    Assignment3.3Writeaprogramtopromptforascorebetween0.0and1.0.Ifthescoreisoutofrange,printanerror.Ifthescoreisbetween0.0and1.0,pri......
  • Tomcat是什么?干嘛用的?(最通俗易懂的讲解)
    Tomcat是什么?干嘛用的?本文可能是最通俗易懂的讲解了!!!一、什么是tomcat?Tomcat是常见的免费的web服务器。Tomcat这个名字的来历,Tomcat是一种野外的猫科动物,不依赖人类,独立......
  • Collection 和 Collections 有什么区别?
    Collection是一个集合接口,它提供了对集合对象进行基本操作的通用接口方法,所有集合都是它的子类,比如List、Set等。Collections是一个包装类,包含了很多静态方法,不能被......
  • HashMap 和 Hashtable 有什么区别?
    存储:HashMap运行key和value为null,而Hashtable不允许。线程安全:Hashtable是线程安全的,而HashMap是非线程安全的。推荐使用:在Hashtable的类注释可以看到,Hash......
  • 设计模式究竟是什么
    什么是设计模式?设计模式是一套由前辈总结的代码设计经验,经过反复的实践,根据这套理论,大家可以写出易维护、易拓展、复用率高的代码,经常被面向对象语言的开发者使用。Java......
  • BIO、NIO、AIO 有什么区别?
    BIO:BlockIO同步阻塞式IO,就是我们平常使用的传统IO,它的特点是模式简单使用方便,并发处理能力低。NIO:NonIO同步非阻塞IO,是传统IO的升级,客户端和服务器端通过Chann......
  • 【问题】为什么 System.Timers.Timer 更改间隔时间后的第一次触发时间是设定时间的三
    【问题】为什么System.Timers.Timer更改间隔时间后的第一次触发时间是设定时间的三倍?独立观察员2022年9月4日在编写“Wifi固定器 [1]”程序时,按如下方式使......
  • android 存储
    Androiddeveloper数据和文件存储概览AndroidgetExternalStorageDirectory()和getExternalFilesDir()的区别Android文件存储路径getFilesDir()与getExternalFilesDir......
  • 【Azure 存储服务】调用REST API获取Stroage Account Table中所有的Entity计数 -- Cou
    问题描述在StorageAccount的使用中,如果想获取Table中全部Entity的计数以及大小,如果是RESTAPI方式,如何来获取呢? 问题解答在Azure中,所有服务的Metrics部分,都可以通过A......
  • 为什么一定要学习股票投资知识
    从大的环境来说,为了避免银行的坏账。顶层就设计直接扩大融资(将企业从银行的贷款转移到直接从股市二级市场融资)。所以股市就一定是一个长期走牛的行情。如果股市长期走熊就......