我有以下代码:
#include <stdio.h>
#include <stdlib.h>
typedef union stateof stateof;
union stateof
{
stateof* foo;
double* bar;
};
typedef struct hunch hunch;
struct hunch{
double* first;
double* second;
};
void main(){
#define write(x) printf("%d \n",x);
int* storage = 0;
stateof* un = (stateof*)&storage;
un->foo = 300;
write(storage);
un->bar = 600;
write(storage);
hunch* h = (hunch*)&storage;
h->first = 1200;
write(storage);
h->second = 1600;
write(storage);
}
该程序的输出是:
300
600
1200
1200
这里发生了什么?
un->{foo,bar}
和h->{first,second}
语句在绝对不指向有效结构时执行是什么意思?在此期间究竟发生了什么,为什么联合的输出与结构的输出不同?
答案 0 :(得分:6)
您的程序会导致各种未定义的行为。你可以得到任何可以想象的输出。编译此代码时,您的编译器可能会给您各种警告 - 尝试修复它们,您应该朝着更好的方向前进。
假设你有一个正常的系统类型,你可以解释你获得输出的原因:
un->foo
会使用值storage
覆盖300
- 然后将其打印出来。un->bar
会使用值storage
覆盖600
- 然后将其打印出来。h->first
会使用值storage
覆盖1200
- 然后将其打印出来。h->second
(危险)用值1600
覆盖一些内存,然后再次打印storage
- 它仍然是1200
。答案 1 :(得分:2)
我将详细描述所有内容。
int* storage = 0;
- 在堆栈上创建一个零值的指针(换句话说,指向NULL)。
stateof* un = (stateof*)&storage;
- un
指向storage
的指针位置。因此un
指向storage
的值,该值现在等于0.
un->foo = 300;
- 将{300}分配给storage
(让我们考虑storage
类似于某些int
值,因为事实上这是一个指针并不重要) ,现在storage == 300
。
un->bar = 600;
- 与前一个相同,因为un
是一个联合,其所有字段实际上只是一个字段的不同名称(嗯,其union
的定义)
h->first = 1200;
和h->second = 1600;
与前面的情况类似,只有一个例外,这里的值被分配给结构中的不同字段(内存中的不同位置)。
write(storage);
- 打印storage
(指针)的值,但不打印storage
指向的值(*storage
)。
当然,最后但并非最不重要:从来没有像任何一样的代码! :)
答案 2 :(得分:0)
我们不知道会发生什么。语言标准没有说。
编写程序时,您和编译器之间存在隐含的契约。如果你编写了一个正确的程序,它必须生成一个与源代码完全相同的可执行文件。
使用
等代码时stateof* un = (stateof*)&storage;
你告诉编译器“我确信&storage
实际上指的是一个工会状态。相信我,我知道我在做什么!”。
编译器认为“如果你这样说......”,并采取相应的行动。但是,当你违反合同时,可以自由地做任何事情。我们只是不知道输出是什么,或者是否会有一个输出。