问题描述
我试图了解以下代码中的类型转换在做什么
UA_Variant Variant;
Int32_t Variable;
variable = *(int32_t *) Variant.data;
printf("%d",variable);
这是 UA_Variant 的结构
typedef struct
{
const UA_DataType *type; /* The data type description */
UA_VariantStorageType storageType;
size_t arrayLength; /* The number of elements in the data array */
void *data; /* Points to the scalar or array data */
size_t arrayDimensionsSize; /* The number of dimensions */
UA_UInt32 *arrayDimensions; /* The length of each dimension */
} UA_Variant;
这一行发生了什么
variable = *(int32_t *) Variant.data;
是否将 Variant 中的数据类型转换为 int32_t,然后将其指针放入变量中,如果是这样,为什么我可以打印出存储在变量中的值?
解决方法
让我们分多个步骤解开这个语句:*(int32_t *) Variant.data
首先,我们有 Variant.data
,根据 void*
结构,它是一个 UA_Variant
。这意味着它只是一个包含内存地址的数字。
然后,使用 (int32_t *)
将 void*
转换为 int32_t*
。 Variant.data
指向的数据随后将被解释为指向 int32_t
类型数据的指针。 我坚持解释而不是强制转换。
最后,您使用 *
运算符取消引用它。因此,变量 variable
包含由 Variant.data
指向的数据,解释为有符号的 32 位值。这意味着,如果 Variant.data
指向的数据是其他一些数据类型,例如 float
s,则变量中的结果值看起来是随机的,并且取决于未定义的行为。这是因为不同的平台以不同的方式实现每种数据类型。
由于这个变量是一个值,你可以像其他任何变量一样打印它。
,您的 data
结构的 UA_Variant
成员被定义为 void*
,这意味着它指向一个对象未指定类型。这种“空指针”不能解除引用。
因此,如果您的 data
的特定 Variant
成员指向一个将被视为 int32_t
类型的对象的对象,则该指针本身 必须首先转换为正确的指针类型 (int32_t*
);然后,它可以被取消引用。
variable = *(int32_t *) Variant.data;
行可能通过添加一些括号更容易理解。这是等效的代码:
variable = *( (int32_t *)(Variant.data) );