任何熟悉此宏定义的人:
#define CrashData (*((CRASH_DATA *)CRASHDATA_ADDRESS))
,其中
CRASH_DATA is a typedef struct
CRASHDATA_ADDRESS is 0xF3F80UL
我怀疑我们正在创建一个名为CrashData的结构变量,该变量是从addrees放置到右前进的?
感谢您的帮助,Pointer声明令人困惑。
答案 0 :(得分:2)
我怀疑我们正在创建一个名为CrashData的结构变量,该变量是从addrees放置到右前进的?
不,不完全是。
首先,在任何地方都没有变量。当您将代码称为宏定义时,您的说法正确;因此,代码定义了一个名为CrashData
的宏,它与变量完全不同。
因此,让我们看一下宏观的替换文字:
(*((CRASH_DATA *)CRASHDATA_ADDRESS))
从内部开始,您声称CRASHDATA_ADDRESS
是 0xF3F80UL
,我将其解释为意味着它实际上是一个宏,{{1}常量作为替换文本。
unsigned long
只能是强制转换运算符,因此听到(CRASH_DATA *)
是CRASH_DATA
ed类型别名,或者可能是扩展到此类的宏,这并不足为奇。演员表的结果是指向typedef
的指针。 可能特别指向CRASH_DATA
指定的地址处的内存块,但标准仅表示
结果是实现定义的,可能没有正确对齐, 可能不会指向引用类型的实体,并且可能是a 陷阱表示。
演员表的结果括在括号中,并且取消引用操作符(一元CRASHDATA_ADDRESS
)将应用于它。取消引用指针的结果是指定指针指向的对象的左值。
取消引用的结果括在括号中,这些括号服务于普通的分组角色。这很有用,因此在使用宏时,运算符优先级不会产生令人惊讶的效果。
总的来说,宏的意图似乎是表示一个表达式,它表示一个从*
开始的内存块,就好像它是{{1}类型的对象一样}}。由于CRASHDATA_ADDRESS
是结构类型,因此您可以通过CRASH_DATA
运算符访问其成员:
CRASH_DATA
虽然如果.
是一个变量,你可能会编写类似的代码,但它不是一个变量,并且它的行为方式与变量不同。
答案 1 :(得分:0)
首先,((CRASH_DATA *)(CRASHDATA_ADDRESS))
是一个类型转换,告诉编译器将CRASHDATA_ADDRESS
中定义的地址视为指向CRASH_DATA
类型项的指针。
接下来,star(*)运算符将取消引用指针。由于它是指向结构的指针,因此一旦引用,您就可以通过点(。)运算符访问任何结构的成员。
您应该能够访问这样的数据:
CrashData.some_struct_member
无论如何,重要的是要明白你不是在创造'一个新的struct变量,你只是告诉编译器将存储在内存地址0xF3F80UL的数据视为CRASH_DATA
类型的变量。