C++ 似乎将我的十六进制无关紧要的零变成了 Fs

标签 c++

我正在构建一个类,它接受一个十六进制值数组,将它们存储在私有(private)属性中,然后将

#include <iostream>

class RFIDData {
public:
    static const uint8_t idLength = 10;

private:
    int idArray[idLength] = {0};
    uint8_t currentIndex = 0;

public:
    void addIdElement(char element) {
        this->idArray[this->currentIndex] = element;
        this->currentIndex++;
    }
    void printArray() {
        for (uint8_t i = 0 ; i < idLength; i ++){
            std::cout << std::hex << this->idArray[i];
        }
        std::cout << std::endl;
    }
};

int idArray[] = {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11};

int main(int argc, const char * argv[]) {

    RFIDData rfid;

    for (uint8_t i = 0; i < 8; i++){
        rfid.addIdElement(idArray[i]);
    }
    rfid.printArray();
}

我遇到的问题是,当我单步执行代码并查看添加到数组中的私有(private)属性值时,数字存储在 F 中,而不是数字中无关紧要的 0,而我不知道为什么。

例如十六进制值 0xaa 被存储为 0xffffffaa

Example image showing the oddity

我对 C++ 很陌生,并且正在尝试学习它。我确定这是我误解的东西,只是在寻找正确方向的一点。

最佳答案

char 是有符号的还是无符号的取决于你的平台和工具链,但它通常是有符号的。使用表达式 0xAA 初始化的带符号 char,将 int 传递给 addIdElement 时会发生这种情况,其值为 -86(从技术上讲这不是保证,但它遵循常见的二进制补码实现和编译器不想做不必要的工作)。

将此值转换回 32 位 int (idArray) 会尝试保持值 -86,结果为 0xFFFFFFAA。这是 sign extension .

您可能希望专门存储 unsigned char,以便您的值和转换都明确符合您的意图。在下面的示例中,我将其提取到名为 IdType 的自己的类型别名中,以确保整个代码的一致性:

#include <iostream>

class RFIDData {
public:
    using IdType = uint8_t;
    static const IdType idLength = 10;

private:
    IdType idArray[idLength] = {0};
    IdType currentIndex = 0;

public:
    void addIdElement(const RFIDData::IdType element) {
        this->idArray[this->currentIndex] = element;
        this->currentIndex++;
    }
    void printArray() {
        for (IdType i = 0 ; i < idLength; i ++){
            std::cout << std::hex << (unsigned int)this->idArray[i];
        }
        std::cout << std::endl;
    }
};

RFIDData::IdType idArray[] = {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11};

int main(int argc, const char * argv[]) {

    RFIDData rfid;

    for (size_t i = 0; i < 8; i++){
        rfid.addIdElement(idArray[i]);
    }
    rfid.printArray();
}

// Output: aabbccddeeff01100

( live demo )

请注意,在将 ID 值插入 std::cout 时,我还必须应用转换,因为 uint8_t 通常是 unsigned char并且标准库的 IOStreams 部分对这些进行了特殊处理(或者更确切地说,它们通过将您的数字按词法转换为它们的 ASCII 表示来对它们进行特殊处理)。

关于C++ 似乎将我的十六进制无关紧要的零变成了 Fs,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54725084/

相关文章:

c++ - 使用 sstream 验证失败

c++ - 如何生成嵌入所有文件的 C++ 安装程序?

c++ - C++函数模板在汇编中是如何实现的?

c++ - 一定时间后中断线程,等待时不会阻塞

c++ - "ambiguous overload for ' operator[] '"如果存在到 int 的转换运算符

c++ - 是否可以修改STL并制作自定义成员函数?

c++ - 在 MSVC 上的数组初始化期间调用的析构函数没有复制或移动构造函数

C++字符串到双重转换

c++ - 什么是构造函数在c++中的实际应用

c++ - 我的老师应该在我的高级 C++ 课上讲什么? [需要的建议]