为什么下面两个对f
的调用给出不同的输出?
#include"stdio.h"
typedef union {
int value_int;
char value_char;
} my_union_t;
void f(int x)
{
printf("x: %d\n", x);
}
void main()
{
my_union_t u;
u.value_int = 7;
my_union_t * p_u = &u;
f( (int) p_u );
f( p_u->value_int );
}
输出:
x: -393095784
x: 7
2条答案
按热度按时间vxf3dgd41#
(int) p_u
取一个指针指向一个并集,该指针是一个地址,并将其转换为int
。您的输出看起来与我预期的完全一样。-393095784
是某个指针(RAM内存中的变量地址)的有符号整数表示。p_u->value_int
从联合体中读取value_int
,看起来和我预期的完全一样。还要知道p_u->value_int
完全等价于(*p_u).value_int
。*
被称为"解引用操作符"。它读取指针的"内容",或者换句话说,获取指针所指向的地址中存储的内容。*p_u
表示"读取p_u
指针所指向的内容",其内容是并集本身。some_ptr->
是(*some_ptr).
的简写。请注意,当您将指针地址强制转换为
int
时,指针地址会从无符号值溢出到有符号值。如果您没有将其强制转换为int,它将如下所示:如上图所示,64位地址打印输出(第1块)和"精确指针大小"打印输出(第三块)是相同的地址。这意味着我运行程序的硬件架构使用64位指针。这也可以通过打印
sizeof(void*)
来获得任何指针的大小,* 注意这里使用void*
只是为了方便。实际上,您可以在那里使用任何指针类型或实际的指针变量,因为在给定的硬件架构上,所有指针类型的指针大小都相同。*上面的输出是由这个程序产生的,你可以在这里实时运行:https://onlinegdb.com/r1YSjZt4_:
另请参阅您问题下方的评论。
参考文献:
t2a7ltrp2#
正如另一个答案所指出的,您不希望将指针强制转换为int型。您需要解引用。
编译器不允许这样做:
f((int) u);
但是,您可以获取地址,强制转换为整数指针,然后解引用:
f(*(int *) &u)
确实是
u.value_int == *(int *) &u
。这似乎是您所能得到的最接近于“将联合强制转换为整数”的方法。