在我之前的回答中,我将 struct
转换为 char
,提取单个字节的数据,然后将值显式转换为 char
,然后赋值给一个 int。
代码 list
myStruct_t structToTest = { 16, 'A'};
myStruct_t referenceStruct;
memset(&referenceStruct, 0xFF, sizeof(myStruct_t));
int t1 = (char)(*(((char*)&structToTest)+i));
int t2 = (char)(*(((char*)&referenceStruct)+i));
printf("Byte #%02d - Test Struct:0x%02X - Reference Structs:0x%02X\n", i, t1, t2);
当我打印出来时,两个十六进制值之一按预期打印,但另一个似乎打印的比我想要的多:
输出
Byte #00 - Test Struct:0x10 - Reference Struct:0xFFFFFFFF
Byte #01 - Test Struct:0x00 - Reference Struct:0xFFFFFFFF
Byte #02 - Test Struct:0x00 - Reference Struct:0xFFFFFFFF
Byte #03 - Test Struct:0x00 - Reference Struct:0xFFFFFFFF
Byte #04 - Test Struct:0x41 - Reference Struct:0xFFFFFFFF
Byte #05 - Test Struct:0x00 - Reference Struct:0xFFFFFFFF
Byte #06 - Test Struct:0x00 - Reference Struct:0xFFFFFFFF
Byte #07 - Test Struct:0x00 - Reference Struct:0xFFFFFFFF
如果我对 0xFF
文字显式执行逻辑 AND 操作,我会得到预期的输出:
代码 list
int t1 = (char)(*(((char*)&structToTest)+i)) & 0xFF;
int t2 = (char)(*(((char*)&referenceStruct)+i)) & 0xFF;
输出:
Byte #00 - Test Struct:0x10 - Reference Structs:0xFF
Byte #01 - Test Struct:0x00 - Reference Structs:0xFF
Byte #02 - Test Struct:0x00 - Reference Structs:0xFF
Byte #03 - Test Struct:0x00 - Reference Structs:0xFF
Byte #04 - Test Struct:0x41 - Reference Structs:0xFF
Byte #05 - Test Struct:0x00 - Reference Structs:0xFF
Byte #06 - Test Struct:0x00 - Reference Structs:0xFF
Byte #07 - Test Struct:0x00 - Reference Structs:0xFF
为什么我使用的屏蔽操作是必要的?无论如何,显式转换都不会将数据截断为 8 位吗?
谢谢!
最佳答案
是的,但是当您将 signed char
转换为 signed int
时,符号位会被扩展.因此,如果这就是您的意思,请使用无符号类型。
通常使用 unsigned
类型比屏蔽更好,因为它清楚地表达了您的意图。它还可能会生成更高效的代码,尽管编译器可能会优化掉不必要的符号扩展和掩码操作。
由于我假设您的数据实际上不是字符而是短二进制代码,因此您可能应该使用 uint8_t
。
关于转换为 (char) 并分配给 (int) 不会清除 MSB,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25167057/