【发布时间】:2026-02-21 00:20:05
【问题描述】:
在超过 16 字节的 c 结构中,如果第 16 字节是 2 字节元素,则会出现问题。让我用代码解释一下:
struct test{
unsigned int a : 16;
unsigned int b : 16;
unsigned int c : 16;
unsigned int d : 16;
unsigned int e : 16;
unsigned int f : 16;
unsigned int g : 16;
unsigned int h : 8;
unsigned int i : 16;
};
int main(int argc, char *argv[]){
//bytes 0, 1, 16, 17 are all equal to 0x31
unsigned char *data = "1134567890123451189";
struct test *testStructure = (struct test*) data;
printf("%X %X\n", testStructure->a, testStructure->i);
return 0;
}
输出:
3131 3831
为什么'i'不等于'a'? 'i' 跳过了字节 16 并使用了字节 17 和 18。这是怎么回事?
【问题讨论】:
-
演员阵容完全是狂野的,它调用了未定义的行为,因为它违反了严格的别名。
-
字节 0,1,15 和 16 是 '1' (0x31),所以不是字节 17,它是 '8'。此外,这不仅仅是一个结构,而是一个位域。
-
见这里*.com/questions/1490092/…,你想要做的是(据我所知)真的不便携。您必须查看编译器的文档才能弄清楚到底发生了什么。
-
您看到“跳过”字节的原因是因为每个字段都必须在正确的边界上“对齐”。因此,在 8 位字段之后是一个“虚拟”对齐字节,因此最后的 16 位字段正确对齐。此外,您的硬件体系结构的“字节序”是这样的,即每个 16 位字段具有在 char 数组中看到的顺序的字节,但 16 位字段首先读取最右边的字节。如果您以“12”开始 char 数组
data,则“字节序”会更加明显(或者如果您不熟悉“字节序”,则会更加混乱