我正试图理解以下代码中的类型转换功能
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
,它是根据UA_Variant
结构的void*
。这意味着它只是一个包含内存地址的数字。
然后,使用(int32_t *)
将该void*
强制转换为int32_t*
。Variant.data
所指向的数据随后将被解释为指向类型为int32_t
的数据的指针我坚持诠释而非铸造
最后,使用*
运算符取消引用它。结果,变量variable
包含由Variant.data
指向的数据,该数据被解释为有符号的32比特值。这意味着,如果Variant.data
指向的数据是其他数据类型,如float
s,则变量中的结果值将看起来是随机的,并取决于未定义的行为。这是因为不同的平台对每种数据类型的实现方式不同。
由于此变量是一个值,因此您可以像打印其他变量一样打印它。
UA_Variant
结构的data
成员被定义为void*
,这意味着它指向一个未指定类型的对象。这样的";空指针";无法取消引用。
因此,如果Variant
的特定data
成员指向的对象将被视为int32_t
类型的对象,则指针本身必须首先强制转换为正确的指针类型(int32_t*
(;然后,它可以被取消引用。
行variable = *(int32_t *) Variant.data;
可能更容易理解,添加了一些括号。这是等效代码:
variable = *( (int32_t *)(Variant.data) );