为什么这个宏体中有类型转换?
Why is there a typecast in this macro body?
我学的是计算机工程,这里的老师总是告诉我们要这样定义一个µC地址:
#define FIO0DIR (* (unsigned int *) 0x2009C000) //GPIO direction register from the lpc1769
但他们从未真正解释过原因或正在发生的事情。
所以我的问题是:为什么演员在那里?
why the cast at all?
因为0x2009C000
是一个整型常量。不是地址。 C 类型系统将整数与地址区分开来,即使目标体系结构可能不会。它允许对它们进行各种约束的转换,但这两种类型 not 是一回事。
您需要转换以将整数常量转换为正确的指针类型,因此您可以取消引用它并访问该地址中的内容。
引用 C11
,§6.5.3.2,地址和间接运算符
The operand of the unary *
operator shall have pointer type.
就其本身而言,0x2009C000
是一个 整数常量(如第 6.4.4.1 章中所述),而不是指针类型。
但是,由于我们打算将此整数常量用作 地址,并且需要推导地址以获得值,因此存在强制转换。
强制转换告诉编译器将整数常量值视为指向unsigned int的指针,然后,解引用运算符作用于指针 获取存储在该内存位置的值。
请注意,不要将此视为普遍适用性。一个整数常量值是否可以表示一个(有效的)地址位置,在很大程度上取决于平台和环境。
您所知道的是,您的控制器映射到地址 0x2009C000,但要操作它,您需要定义要在该地址存储或读取的数据类型。这就是 C 等高级语言中的类型:指定在某个地址存储何种数据、其长度(以字节为单位)及其表示形式(例如 2 的补码中的整数)。所以:
(unsigned int *)0x2009C000
表示将常量0x2009C000视为存储无符号整数的地址。
* ((unsigned int *)0x2009C000)
表示存储在存储无符号整数的地址的变量,只是存储在给定地址的无符号整数变量。
我学的是计算机工程,这里的老师总是告诉我们要这样定义一个µC地址:
#define FIO0DIR (* (unsigned int *) 0x2009C000) //GPIO direction register from the lpc1769
但他们从未真正解释过原因或正在发生的事情。
所以我的问题是:为什么演员在那里?
why the cast at all?
因为0x2009C000
是一个整型常量。不是地址。 C 类型系统将整数与地址区分开来,即使目标体系结构可能不会。它允许对它们进行各种约束的转换,但这两种类型 not 是一回事。
您需要转换以将整数常量转换为正确的指针类型,因此您可以取消引用它并访问该地址中的内容。
引用 C11
,§6.5.3.2,地址和间接运算符
The operand of the unary
*
operator shall have pointer type.
就其本身而言,0x2009C000
是一个 整数常量(如第 6.4.4.1 章中所述),而不是指针类型。
但是,由于我们打算将此整数常量用作 地址,并且需要推导地址以获得值,因此存在强制转换。
强制转换告诉编译器将整数常量值视为指向unsigned int的指针,然后,解引用运算符作用于指针 获取存储在该内存位置的值。
请注意,不要将此视为普遍适用性。一个整数常量值是否可以表示一个(有效的)地址位置,在很大程度上取决于平台和环境。
您所知道的是,您的控制器映射到地址 0x2009C000,但要操作它,您需要定义要在该地址存储或读取的数据类型。这就是 C 等高级语言中的类型:指定在某个地址存储何种数据、其长度(以字节为单位)及其表示形式(例如 2 的补码中的整数)。所以:
(unsigned int *)0x2009C000
表示将常量0x2009C000视为存储无符号整数的地址。
* ((unsigned int *)0x2009C000)
表示存储在存储无符号整数的地址的变量,只是存储在给定地址的无符号整数变量。