gpt4 book ai didi

无法理解这个 union

转载 作者:太空宇宙 更新时间:2023-11-04 04:02:54 24 4
gpt4 key购买 nike

我在 ideone.com 上试过这段代码,它符合要求,但我无法解释发生了什么,任何帮助都会很棒:)

代码如下:

#include <stdio.h>


typedef union {
unsigned char* g_pointer;
struct {
unsigned short local_addr;
unsigned char globle_page;
} g_l;
} Gld_WordType;


int main()
{
int Idx;
Gld_WordType test;
test.g_l.globle_page = 0x13;
test.g_l.local_addr = 0xfff0;

printf("g_pointer: %x\n
local_addr: %x\n
globle_page: %x\n",
test.g_pointer,
test.g_l.local_addr,
test.g_l.globle_page);

test.g_pointer++;

printf("g_pointer: %x\n
local_addr: %x\n
globle_page: %x\n",
test.g_pointer,
test.g_l.local_addr,
test.g_l.globle_page);

return 0;
}

结果是:

g_pointer: 13fff0
local_addr: fff0
globle_page: 13
g_pointer: 13fff1
local_addr: fff1
globle_page: 13

如果我简单地调换 local_addrgloble_page 的顺序,结果就会不同:

typedef union {
unsigned char* g_pointer;
struct {
unsigned char globle_page; // Changed order here.
unsigned short local_addr; // And here
} g_l;
} Gld_WordType;

这次的结果是:

g_pointer: fff00013
local_addr: fff0
globle_page: 13
g_pointer: fff00014
local_addr: fff0
globle_page: 14

OK,我对这个问题的理解就到此为止,如有错误,请指出。

1、第一个例子中的union是这样组成的(globle_page前面的local_addr)

############  #############
# # # #
# g_pointer# # local_addr#
# # # MSB or LSB#
############ #############
#############
# #
# local_addr#
# MSB or LSB#
#############
##############
# #
# globle_page#
# #
##############

如果 globle_page 定义在 local_addr 之前,布局是这样的:

############  ##############
# # # #
# g_pointer# # globle_page#
# # # #
############ ##############
##############
# #
# local_addr #
# MSB or LSB #
##############
##############
# #
# local_addr #
# MSB or LSB #
##############

所以在情况 1 中(local_addr 定义在 globle_page 之前),如果 g_pointer 的值发生变化,local_addr的 MSB 或 LSB 也会改变,但为什么它实际上加了一个?因为我知道我的平台是Big-Endian byte order,所以local_addr的MSB应该改了,为什么LSB改了?

情况2(globle_page定义在local_addr之前),我可以解释为g_pointer的值加一,对应的地址`globle_page' 也添加了一个,但是由于情况 1,我不太确定这一点。

谁能告诉我这里发生的事情的确切答案?如果我没有正确描述问题,请原谅我糟糕的英语。

顺便说一句,我使用的平台没有字节对齐问题。所以 sturct 是一个字节一个字节的布局。

最好的问候,盛运

最佳答案

could anyone tell me the exact answer of what is happening here?

首先要知道的也是最重要的事情是结果是未定义的行为。您可能会看到不同编译器的不同结果——甚至使用不同选项的相同编译器。最常见的替代行为是,当您修改一个字段时,其他字段要等到将来某个时间才会更改。我在表格的过去写了一些测试代码

// assign to the first field
// print the second field
// print the second field

并且第一个打印显示第二个字段的前值,第二个打印显示第二个字段的更新值。

在您真正了解您在处理别名和未定义行为方面所做的事情之前,您应该永远以这种方式使用union .

接下来要知道的是指针很少有 1 个字节长。在大多数现代机器上,它们往往是 4 或 8 个字节。

关于数据布局,接下来要了解的是有时 structs 会被填充。对于结构

struct {
char a;
short b;
};

我认为布局很可能是

<one byte of a>  <unused byte>  <two bytes of b>

作为

<one byte of a>  <two bytes of b>

我不会惊讶地看到

<one byte of a>  <3 unused bytes>  <two bytes of b>

事实上,根据您的经验结果,我希望您有 4 字节的指针,而这最后一种可能性是 struct 的实际布局方式。

您可以使用 sizeofoffsetof 函数来准确确定事物。 sizeof 会告诉您每种类型有多少字节长,offsetof 会让您准确确定结构或 union 中每个字段的开始位置。

另一点需要注意的是,指针并不总是像整数一样布局。此问题取决于您运行的计算机体系结构。不过,我认为所有“常见”的行为都符合您的预期。

关于无法理解这个 union ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9632652/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com