通过属性问题初始化typedef struct

Initialize typedef struct by attribute problem

我定义了一个基于字节的结构,大小为 3 个字节。 (1 packetID 和 2 packetSize)我用 sizeof 函数检查了大小,效果很好:

#pragma pack(1)

typedef struct ENVIRONMENT_STRUCT{
    unsigned char packetID[1];
    unsigned char packetSize[2];
}

我像这样创建了一个变量和预留内存:

ENVIRONMENT_STRUCT * environment_struct = new ENVIRONMENT_STRUCT();

现在我想初始化environment_struct

问题是我试图通过属性初始化这个结构,就像这样:

*environment_struct->packetSize = 100;

但是当我检查这个值时,使用:

std::cout << "Packet Size: " << environment_struct->packetSize << endl;

Result: Packet Size: d

Expected result: Packet Size: 100

如果我要处理数字,我应该使用 csdint 库定义结构吗?例如,u_int8和这种类型的变量。

由于 packetSize 被声明为 char 类型,它被输出为一个字符。 (字符'd'的ASCII码为100...)

尝试将其转换为整数类型:

std::cout << "Packet Size: " << (int)environment_struct->packetSize << endl;

或者,由于您似乎希望将数字存储为 2 字节类型,您可以避免此类转换并简单地将 packetSize 声明为 unsigned short。这将被 cout 解释为整数类型。

当您尝试打印一个字符符号而不是一个整数时,您会得到这个结果。

要修复它,只需转换值或根据需要将其声明为整数。

演员表示例:

std::cout << "Packet Size: " << static_cast<int>(*environment_struct->packetSize) << std::endl;

当你这样做时

ENVIRONMENT_STRUCT * environment_struct = new ENVIRONMENT_STRUCT();

您将 packetSize 初始化为 {0, 0}。那么

*environment_struct->packetSize = 100;

将数组变成{100, 0}。由于当您使用

将数组发送到 cout 时,该数组是一个字符数组
std::cout << "Packet Size: " << environment_struct->packetSize << endl;

它把它当作一个 C 字符串并打印出字符串内容。由于您看到 d,这意味着您的系统正在使用 ascii,因为字符 'd' 具有 100 的整数表示。要查看 100,您需要将其转换为 int,例如

std::cout << "Packet Size: " << static_cast<int>(*environment_struct->packetSize) << endl;

请注意,由于 packetSize 是一个包含两个字符的数组,您实际上不能分配一个占据整个 space 的值。如果你想要这个那么你需要使用像

这样的固定宽度类型
typedef struct ENVIRONMENT_STRUCT{
    uint8_t packetID; // unsigned integer that is exactly 8 bits wide.  Will be a compiler error if it does not exist
    uint16_t packetSize; // unsigned integer that is exactly 16 bits wide.  Will be a compiler error if it does not exist
};

int main()
{
    ENVIRONMENT_STRUCT * environment_struct = new ENVIRONMENT_STRUCT();
    environment_struct->packetSize = 100;
    std::cout << "Packet Size: " << environment_struct->packetSize << std::endl;
}

让我们首先考虑一下 *environment_struct->packetSize = 100; 的作用。它将 ENVIRONMENT_STRUCT::packetSize 的第一个字节设置为 100。更常规的语法是:environment_struct->packetSize[0] = 100.

确实没有办法以表达式 std::cout << environment_struct->packetSize 导致输出 100 的方式初始化结构。让我们考虑一下它的作用。 environment_struct->packetSize 是一个数组,在这种情况下会衰减为指向第一个元素的指针。插入到字符流中的字符指针被解释为空终止字符串。幸运的是,您已经对 environment_struct->packetSize 的第二个字节进行了值初始化,因此您的数组确实以空值终止。第一个字节的值被解释为编码字符。在您的系统编码中,碰巧 d 字符被编码为值 100。

如果你想打印你设置为100的environment_struct->packetSize的第一个字节的数值,你可以使用:

std::cout << "Packet Size: " << (int)environment_struct->packetSize[0] << endl;