带有初始化变量和负数的 memcpy

memcpy with initialized variable and negative numbers with cast

我有

    QByteArray bytes    // Fullfilled earlier   
    char id_c = bytes[7];   
    int _id;
    _id = 0; // If I comment this result would be different
    memcpy(&_id, &id_c, 1); 
    int result = _id;

我有 _id 变量,如果我注释“_id=0”结果变量结果将与负数不同。为什么?为什么用 0 初始化 _id 会有所不同?! 我怎样才能替代使用“_id=0”但不使用 memcpy 和不需要的转换来获得相同的结果?

这不是我的代码。我很感兴趣如何在没有愚蠢的铸件的情况下正确地获得相同的结果。

_id = 0叫做给变量_id赋值0,如果你评论说那我们就不能确定那个_id 里存的是什么,你只更新其中的一个字节,因为它是 int 类型,它的大小超过一个字节。

正确。

因为这条语句:

memcpy(&_id, &id_c, 1); 

只是将单个字节从 &id_c 复制到表示 4 字节整数 &_id 的地址中。只有 _id 占用的内存的第一个字节才会将任何内容复制到其中。如果没有 _id 的零初始化,则该值的其余三个字节未定义(可能是堆栈中的随机垃圾值)。

“不需要的演员表”有什么问题?这很好,编译器生成了最高效的代码。

QByteArray bytes    // Fullfilled earlier   
int _id = (int)(bytes[7]);
int result = _id;

如果你想将无符号字节的符号扩展结果复制到_id,那么这个:

int _id = (signed char)(bytes[7]);

您可以尝试这些 net/host 字节顺序转换:

on linux

on windows

唯一的区别是要使用的 header 文件;如果需要 cross-platform 编程,您可以使用预处理器技巧来确定平台并选择适当的 header。更好的方法是使用 C++20 特性 std::endian。但是你需要自己处理转换:

#include <bit>
#include <climits>
int int_cvt(int x){
    if constexpr (endian::native==endian::big)
       return x;
    y=0;
    while(x){
        unsigned char c=x;
        x>>=std::CHAR_BIT;
        y<<=std::CHAR_BIT;
        y+=c;
    };
    return y;
};

干杯, 调频