大端存储与小端存储

本文介绍了字节序的概念,包括大端和小端的存储方式,并指出字符串在内存中不涉及字节序。在网络通信中,通常使用大端字节序。提供了一个C++程序来判断和转换字节序。在跨平台的网络程序设计中,了解和处理字节序问题至关重要。

1. 什么是大端和小端

  1. Little-Endian就是低位字节存放在内存的低地址端高位字节存放在内存的高地址端
  2. Big-Endian就是高位字节 存放在内存的低地址端低位字节存放在内存的高地址端
    即:低低高高为小端,高低低高为大端;

例如:0x12345678的小端存储为:

内存地址小端大端
0x40000x780x12
0x40010x560x34
0x40020x340x56
0x40030x120x78

2. 为什么会有大小端模式之分呢?字符串分大小端吗?

内存的单位是字节,对于字符来说,char是一个字节,不受主机字节序和网络字节序的影响,在内存中就一个单元,没有前后之分。所以对于字符或字符串而言,不存在大小端之分;
但是当是组合内存空间时,因为有多个内存单元,就有前后之分,而小端和大端字节序的差别就在于怎么对这个前后内存单元进行组合。

3. 网络通信时的大小端

请添加图片描述

套接字通信过程中操作的数据都是大端存储的,包括:接收/发送的数据、IP地址、端口。
请添加图片描述请添加图片描述

请添加图片描述

4.大小端判断方法:

#include <iostream>
#include <arpa/inet.h>
using namespace std;

//判断系统是大端存储还是小端存储:可以通过'union 联合体'进行判断;
//大端:低字节存储在高地址;
//小端:低字节存储在低地址;
int Check_Big_End_Or_Small_End()
{
    union uni{
        uint16_t a;
        char c;
    };
    uni u;
    u.a=1;

    //由于union是联合体,编译器分配的内存大小与union中最大的数据类型存储一致;
    //如果是大端,则t.c=0x00,则t.c!=1,返回0;
    //如果是小端,则t.c=0x00,则t.c==1,返回0;
    return (u.c==1);
}

//将小端转换为大端存储类型;
int transform()
{
    union uni{
        uint16_t a;
        char c;
    };
    uni u;
    u.a=1;

    //小端存储转换为大端;

    u.a=htons(u.a);
    return (u.c==1);
}

int main()
{
    cout<<Check_Big_End_Or_Small_End()<<endl;//==> 1 小端
    cout<<transform()<<endl;//==> 0 小端转换为大端
    return 0;
}

5.大小端场景:

5.1 网络

对大多数程序员来说,其机器所使用的字节顺序是完全不可见的,我们一般也不需要关心字节存储的顺序.但是,有些时候,字节顺序会成为问题,首先在不同类型的机器(大多数机器是小端存储)之间通过网络传送二进制数据时,一个常见的问题就是当小端法机器产生的数据发送到了大端法机器,或者翻过来的,接收程序时,就会产生混乱,为了解决这个问题,网络应用程序的代码编写必须遵守已建立的关于字节顺序的规则,确保发送方机器将它的内部表示转换成网络标准,而接收方机器则将网络标准转换为它的内部表示;

作者: 苏丙榅
链接: https://subingwen.cn/linux/socket/#5-2-3-%E5%A5%97%E6%8E%A5%E5%AD%97%E5%87%BD%E6%95%B0
来源: 爱编程的大丙

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值