2

我试图了解类型转换在以下代码中的作用

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 然后将其指针放入变量中,如果是这样,为什么我可以打印出存储在变量中的值?

4

2 回答 2

3

让我们分多个步骤解压缩此语句:*(int32_t *) Variant.data

首先,根据结构,我们有Variant.data哪一个。这意味着它只是一个包含内存地址的数字。void*UA_Variant

然后,与(int32_t *)您一起将其void*转换为int32_t*. 指向的数据Variant.data将被解释为指向数据类型的指针int32_t我坚持解释不铸造。

最后,您使用操作员取消引用它*。因此,变量包含被解释为有符号 32 位值variable的指向的数据。Variant.data这意味着,如果 指向的数据Variant.data是其他数据类型,例如floats,则变量中的结果值看起来是随机的,并且取决于未定义的行为。这是因为不同的平台以不同的方式实现每种数据类型。

由于此变量是一个值,因此您可以像打印任何其他变量一样打印它。

于 2020-12-27T16:50:36.033 回答
2

结构的data成员UA_Variant定义为void*,这意味着它指向对象未指定类型。这样的“空指针”不能被取消引用。

因此,如果您的特定data成员Variant指向要被视为类型对象的对象,则必须首先将int32_t指针本身int32_t*强制转换为正确的指针类型( );然后,它可以被取消引用。

variable = *(int32_t *) Variant.data;加上一些括号,这条线可能更容易理解。这是等效的代码:

variable = *( (int32_t *)(Variant.data) ); 
于 2020-12-27T16:51:27.157 回答