qt 关于大端小端的一个实验 简单实验

news/2024/7/8 15:35:41 标签: qt, 开发语言, 简单实验

1.概要

起因我用滚动是x86电脑,我用一个usort  a11a ,我期待转换长的char字符应该是这样的“1aa1”,因为x86是小端的,这也是这个16位 类型的实际内存顺序,但是输出的结果是 “a11a”,难道这环境不是小端?难道qt能智能转换?。但结果是QDataStream默认安装大端保存数据。他再小端的环境这样保存数据。我的代码如下

QDataStream out(&block, QIODevice::WriteOnly);
    out<<b;

我还百度上确认这给结果,但结果是否定的,但现象确和我的推论一样。

1.问题呢1:QDataStream 具有自动修正为大端格式的能力吗?

QDataStream 是 Qt 框架中的一个类,用于序列化和反序列化 Qt 数据类型。关于 QDataStream 是否具有自动修正为大端格式的能力,实际上它并不直接“修正”数据的字节序为大端或小端。相反,QDataStream 在序列化和反序列化数据时,会以一种可移植的方式处理数据,以确保在不同的平台上能够一致地读写数据。

QDataStream 在写入数据时,会以一种特定的格式保存数据,这个格式是 Qt 特定的,并不直接对应大端或小端。当在不同平台上读取这些数据时,QDataStream 会根据当前平台的特性(如字节序)来正确解析这些数据。这意味着,无论数据是在大端还是小端机器上生成的,只要使用 QDataStream 进行读取,它都能够正确地还原原始数据。

这种能力并不是通过“修正”字节序来实现的,而是通过一种与平台无关的数据表示方式来实现的。因此,QDataStream 并不直接修改数据的字节序,而是以一种可移植的方式处理数据,以确保数据的一致性和可移植性。

总的来说,虽然 QDataStream 不直接“修正”为大端格式,但它确实提供了一种在不同平台上一致地读写数据的方法。

2.问题2:QDataStream 保存的字节数据都是按照大端保存的吗

QDataStream 保存的字节数据并不总是按照大端(Big-Endian)方式保存。以下是关于 QDataStream 保存字节数据方式的详细解释:

  1. 字节序的灵活性
    QDataStream 在处理多字节数据(大于一个字节的数据)时,确实涉及字节序的问题。字节序,即多字节数据在内存中的存储顺序,有两种方式:Big-Endian(大端)和 Little-Endian(小端)。在 Big-Endian 中,高位字节存储在低地址端,而 Little-Endian 则相反,低位字节存储在低地址端。

  2. QDataStream 的默认行为
    虽然 Big-Endian 是网络传输和文件存储中常见的字节序,但 QDataStream 的设计考虑到了跨平台的兼容性。它并不总是默认按照 Big-Endian 保存数据。实际上,QDataStream 的行为可能受到其设置或 Qt 版本的影响。

  3. 序列化和反序列化
    QDataStream 主要用于对象的序列化和反序列化。序列化是将对象状态转换为可保存或可传输的形式,而反序列化则是相反的过程。在这个过程中,QDataStream 会以一种可移植的方式处理数据,以确保数据在不同的平台和架构上能够一致地读写。

  4. 平台无关性
    重要的是要理解,QDataStream 的目标是提供一种与平台无关的数据读写机制。这意味着,无论数据是在大端机器还是小端机器上生成的,QDataStream 都应该能够正确地读写这些数据。它不是通过强制使用 Big-Endian 或 Little-Endian 来实现这一点,而是通过其内部的数据表示和处理机制来确保数据的一致性和可移植性。

综上所述,不能简单地认为 QDataStream 保存的字节数据都是按照大端保存的。它的设计目标是提供一种跨平台的数据读写解决方案,而不是固定于某一种字节序。在实际应用中,如果需要特定的字节序处理,可能需要在读写数据前进行显式的转换或设置。

2.代码 

#include <QCoreApplication>
#include <QDebug>
#include <QByteArray>
#include <QIODevice>
#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QByteArray block;
    unsigned short b = 1;
    char c[2];
    std::memcpy(c, &b, 2);
    for(int i=0;i<sizeof(b);i++){
        int d = c[i];
        qDebug()<<i<<":"<<d;
        //cout<<i<<":"<<d;
    }
    QDataStream out(&block, QIODevice::WriteOnly);
    out<<b;
    char* chars = block.data();
    for(int i=0;i<block.length();i++){
        int d = chars[i];
        //char d = 5;
        qDebug()<<i<<":"<<d;
        //cout<<i<<":"<<d;
    }

    qDebug()<<"hello 大小端实验";
    return a.exec();
}

3.运行结果

0 : 1
1 : 0
0 : 0
1 : 1
hello ��С��ʵ��

4.结果 

 我直接输出的内存顺序和QDataStream处理过的顺序完全不同,也就是说,QDataStream把小端的数据序,变成了大端的数据序。

 


http://www.niftyadmin.cn/n/5537324.html

相关文章

【Unix/Linux】$bash-3.2是什么

bash-3.2 指的是Bourne Again Shell&#xff08;Bash&#xff09;的3.2版本。 Bash是一个广泛使用的Unix shell和命令语言&#xff0c;是GNU项目的一部分&#xff0c;也是许多Linux发行版和Unix系统的默认shell。 以下是一些关于Bash 3.2的要点&#xff1a; 1. 兼容性&#…

---java KMP算法---

对于在一段字符串中查找一段字符串&#xff0c;如果用数组遍历的方法那就效率低下&#xff0c;所以产生了效率更高的KMP算法 KMP算法查只需要遍历一次字符串就可以找出第一次出现的目标字符串 要学的话建议区b站看视频&#xff0c;学着由视频学者比较容易 我这里就提供下我实…

初学vue3与ts:获取组件ref实例

/*** 获取组件ref* param {VueComponentIns} 组件实例* returns 组件ref*/ // eslint-disable-next-line export function useCompRef<T extends abstract new (...args: any) > any>(_: T) {return ref<InstanceType<T>>(); }使用 <a-com ref"a…

echarts实现3D柱状图(视觉层面)

一、第一种效果 效果图 使用步骤 完整实例&#xff0c;copy就可直接使用 <template><div :class"className" :style"{height:height,width:width}" /> </template><script>import echarts from echartsrequire(echarts/theme/…

如何在Vue中添加事件监听器

在Vue中添加事件监听器主要有两种方式&#xff1a;在模板中直接添加和使用Vue实例的方法。以下将详细解释这两种方法。 1. 在模板中直接添加 在Vue的模板中&#xff0c;你可以直接在HTML元素上使用v-on指令&#xff08;或其简写形式&#xff09;来监听DOM事件&#xff0c;并在…

Keycloak SSO 如何验证已添加的 SPN 是否生效

使用 Kerberos Ticket 验证&#xff1a; 在客户端计算机上&#xff0c;运行以下命令以获取 Kerberos Ticket&#xff1a; klist检查是否存在与 HTTP/yourdomain.com 相关的票证。如果存在&#xff0c;说明 SPN 已生效。 测试应用程序&#xff1a; 使用具有 HTTP/yourdomain.com…

elasticsearch入门基本知识+使用案例

1、ES逻辑结构 索引-index&#xff1a;相当于db中的数据库名。索引命名规则&#xff1a;小写字母。 类型-type&#xff1a;相当于数据库中的表名&#xff0c;为具有相同字段的文档定义的一个类型。 字段-field&#xff1a;相当于表字段名&#xff0c;文档数据的属性…

[C++]——继承 深继承

一、继承概念 (1)、定义 继承(inheritance)机制是面向对象程序设计使代码复用最重要的手段&#xff0c;它允许程序员在保持原有类特性的基础上进行扩展&#xff0c;增加功能。继承呈现了面向对象程序设计的层次结构&#xff0c;体现了由简单到复杂的认知过程&#xff0c;是类…