我有一个关于 STM32 微控制器的 C 语言类型转换的问题。现在我正在尝试编写自己的库来控制微控制器的外围设备。但我不明白为什么以及何时应该使用像 (uint32_t) 这样的类型转换。
例如,对于 GPIO 配置寄存器,我看到了下一个示例:
#define INPUT_ANALOG ((uint32_t) 0x00)
#define INPUT_FLOATING ((uint32_t) 0x01)
#define INPUT_PUP_PDOWN ((uint32_t) 0x02)
Run Code Online (Sandbox Code Playgroud)
此信息来自数据表(下面附有打印屏幕)。在这里我不明白为什么使用 typecast (uint32_t) 而不仅仅是 0x00 或 0。
我可以将下一个代码用于相同的目的吗?
typedef enum{
INPUT_ANALOG = 0,
IN_FLOATING,
IN_PULL_UP_DOWN,
}PinConfInput_t;
Run Code Online (Sandbox Code Playgroud)
我应该对此代码进行类型转换吗?你能给我推荐一些关于 typecast 的学习资料吗?谢谢
类型转换到unsigned int 或后缀u/U需要使用的值0x00,0x01以及0x02在许多情况下。0x00,0x01并且0x02它们本身是类型的常量int,并且有一些在ints上工作可疑的小东西,例如将它们位移到符号位置时!
如果您取值 0x02 (int) 并将其左移到位 31:30,就会发生这种情况!所以,
0x02 << 30
Run Code Online (Sandbox Code Playgroud)
在整数为 32 位宽的机器上有未定义的行为,而
0x02U << 30
Run Code Online (Sandbox Code Playgroud)
或者
((uint32_t)0x02) << 30
Run Code Online (Sandbox Code Playgroud)
不会。
枚举列表的标识符声明为 ( C11 6.7.2.2p3 )
具有 int 类型的常量,并且可以出现在任何允许的地方。
即是的,他们也需要这些位移位的演员表。
请注意,C 中枚举常量的类型不必是枚举本身的类型:
#include <stdio.h>
enum foo {
bar = 42
};
int main(void) {
printf("An enumeration constant is an %s\n",
_Generic(bar,
int: "int",
unsigned int: "unsigned int",
default: "something else"));
printf("On this implementation the enum foo is %s\n",
_Generic((enum foo) 0,
int: "int",
unsigned int: "unsigned int",
default: "something else"));
}
Run Code Online (Sandbox Code Playgroud)
在GCC会打印出int的枚举常量类型,unsigned int为的类型enum foo。即常量具有与实际枚举不同的类型。
此外,使用超出整数范围的枚举常量是违反约束的;由于0x80000000不能表示为int32 位系统,因此它不能可移植地用作枚举常量:
% gcc enumtest.c -std=c11 -pedantic
enumtest.c:5:11: warning: ISO C restricts enumerator values to range of ‘int’
[-Wpedantic]
5 | bar = 0x80000000
| ^~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)
最后,正如 C 标准所说,枚举本身的类型由编译器决定,一些编译器可能会使用unsigned char短枚举。好吧,即使在那里你也可能需要一个演员表,因为unsigned char将被提升为 a signed int,而不是unsigned int在算术之前。