使用C++确定主机字节序

前言

  • 字节序,就是字节的存储顺序。
  • 而字节是内存中可寻址的最小单位。
  • 8位为一个字节。
  • 所有的信息都是由若干个字节组成的
  • 那么现在的问题就是,对于十六进制数字0x1234,在内存中是如何存储的?
  • 0x1234有2个字节,那么他在内存中有两种存储方式,或者说他有两种表示方式,一种是1234, 一种是3412,注意从左往右,地址从低到高,前者就是大端字节顺序(高位先存储),后者就是小端字节顺序(低位先存储)。

为什么要区分大端和小端?

首先,二者没有优劣,仅仅是不同的方案,就跟你剥鸡蛋壳的时候,从大端打开还是从小端打开一样,都是可以的。贴一下《深入理解计算机系统》中的段子。
在这里插入图片描述
其次,当不同的主机进行通信的时候,以大端方式存储的信息,如果以小端方式进行解析,那显然会出错。所以需要区分。已有一些转换函数,暂时不去研究。

如何确定本机是大端还是小端?

大端小端可以认为是操作系统决定的。不同的操作系统的模式是不一样的,例如安卓和IOS都是小端,那么我的64位Intel处理器的Windows是什么模式呢?

下面来研究一下,在这个过程中可以加深我们对指针、字节、强制转换等知识的理解。

思路
  1. 首先确定一个我们已知的数字,例如0x12345678,用int x 来存储。
  2. 由于我们希望按照字节顺序地打印x在内存中的值,所以我们用一个char* 的指针来指向这个这个x,然后,就可以用这个char * 类型的指针来按序访问字节了。
代码

网上提供的通常是C语言版本,在此特地使用C++语言,同时故意使用reinterpret_cast强制转换,(虽然他看起来比较冗长),他的作用是显式地告诉编译器,我们希望将int型的指针当成char型的指针,这样他的步长就变成了1个字节,而不是4个字节。

#include<iostream>
using namespace std;
int main(){
    unsigned int x = 0x12345678;
    unsigned char* p = reinterpret_cast<unsigned char*>(&x); //用char类型的指针指向x
    for(size_t i=0; i<4; i++){// x有4个字节
        // 将得到的一个字节的数强制转换成整数,再以十六进制输出
        cout << hex << static_cast<unsigned int>(p[i]);
    }
    cout << endl;
}

输出结果

在这里插入图片描述

显然,这说明我的机器是以小端字节顺序来存储整数0x12345678的。

补充:程序中示意的x不含有00,因为00的话cout会有问题,这不属于本次讨论范畴。有时间再整理下C++的格式化输出。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux网络编程是指在Linux操作系统下使用C语言进行网络编程的过程。在Linux网络编程,可以使用一些函来进行字节序转换和处理Socket地址。 关于字节序转换,可以使用以下函: - 主机字节序转网络字节序:htons、htonl函(host to net 无符号short/int) - 网络字节序主机字节序:ntohs、ntohl(net to host 无符号short/int) 关于Socket地址的处理,可以使用以下结构体和函: - sockaddr_storage结构体:表示一个通用的Socket地址结构体,用于封装端口号和IP等信息。 - sockaddr_in和sockaddr_in6结构体:专用于TCP/IP协议族的Socket地址结构体。 - 在网络编程,可以根据地址族来确定使用哪种结构体,并使用相应的函进行处理。 在Linux网络编程,可以使用一些开源项目如Redis、Muduo、TeamTalk等作为学习的参考,其Muduo是一个比较经典的网络编程框架。 需要注意的是,网络编程函的诞生早于IPv4协议时期,因此使用的是struct sockaddr结构体。为了向前兼容,现在sockaddr被退化为(void *)的作用,而具体使用的是sockaddr_in还是sockaddr_in6则取决于地址族,函内部会根据需要进行强制类型转换。 总结起来,Linux网络编程是在Linux操作系统下使用C语言进行网络编程的过程,其涉及到字节序转换和处理Socket地址的相关函和结构体。可以通过学习开源项目和相关资料进一步深入了解和应用网络编程。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值