C指针转换规则
我有以下代码:C指针转换规则,c,pointers,unions,C,Pointers,Unions,我有以下代码: #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 wri
#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);
}
这里发生了什么
当un->{foo,bar}
和h->{first,second}
语句肯定没有指向有效的结构时,执行它们意味着什么?在这段时间内到底发生了什么?为什么联合的输出与结构的输出不同?您的程序会导致各种未定义的行为。你可以得到任何可以想象的输出。当你编译这段代码时,你的编译器可能会给你各种各样的警告——试着修复它们,你应该朝着更好的方向前进
假设您有一个正常类型的系统,您获得所看到的输出的原因可以解释为:
un->foo
会用300
值覆盖storage
——然后打印出来un->bar
会用600
值覆盖storage
——然后打印出来h->首先
用1200
值覆盖存储
——然后打印出来h->second
(危险地)会用1600
值覆盖一些内存,然后再次打印storage
——仍然是1200
un->foo
会用300
值覆盖storage
——然后打印出来un->bar
会用600
值覆盖storage
——然后打印出来h->首先
用1200
值覆盖存储
——然后打印出来h->second
(危险地)会用1600
值覆盖一些内存,然后再次打印storage
——仍然是1200
我将详细描述所有这些
int*存储=0代码>-在堆栈上创建一个零值指针(换句话说,指向NULL)
stateof*un=(stateof*)&storage
-un
指向作为指针的存储器的位置。所以un
指向存储器的值,该值现在等于0
un->foo=300
-将300分配到存储
(让我们考虑存储
类似于某个int
值,因为它实际上是一个指针并不重要),所以现在存储==300
un->bar=600代码>-与前一个相同,因为un
是一个联合体,它的所有字段实际上只是一个字段的不同名称(好吧,它的union
的定义)
h->first=1200代码>和h->秒=1600代码>与前面的情况类似,只有一个例外,这里的值被分配给结构中的不同字段(内存中的不同位置)
写入(存储)代码>-打印存储
(指针)的值,但不打印存储
指向(*存储
)的值
当然,最后但并非最不重要的一点是:永远不要再像那样编写代码了!:) 我将详细描述所有内容
int*存储=0代码>-在堆栈上创建一个零值指针(换句话说,指向NULL)
stateof*un=(stateof*)&storage
-un
指向作为指针的存储器的位置。所以un
指向存储器的值,该值现在等于0
un->foo=300
-将300分配到存储
(让我们考虑存储
类似于某个int
值,因为它实际上是一个指针并不重要),所以现在存储==300
un->bar=600代码>-与前一个相同,因为un
是一个联合体,它的所有字段实际上只是一个字段的不同名称(好吧,它的union
的定义)
h->first=1200代码>和h->秒=1600代码>与前面的情况类似,只有一个例外,这里的值被分配给结构中的不同字段(内存中的不同位置)
写入(存储)代码>-打印存储
(指针)的值,但不打印存储
指向(*存储
)的值
当然,最后但并非最不重要的一点是:永远不要再像那样编写代码了!:) 我们不知道会发生什么。语言标准没有说
当你编写一个程序时,你和编译器之间有一个隐含的契约。如果你写了一个正确的程序,它必须产生一个完全按照源代码所说的执行的可执行文件
当你使用像
stateof* un = (stateof*)&storage;
您正在告诉编译器“我确信&storage
实际上指向一个联合状态。相信我,我知道我在做什么!”
编译器会思考“如果你这么说……”,并相应地采取行动。但既然你已经违反了合同,那么你可以自由地做任何事情。我们只是不知道输出会是什么,或者是否会有输出。我们不知道会发生什么。语言标准没有说
当你编写一个程序时,你和编译器之间有一个隐含的契约。如果你写了一个正确的程序,它必须产生一个完全按照源代码所说的执行的可执行文件
当你使用像
stateof* un = (stateof*)&storage;
你是在告诉编译器“我确信