我正在为微处理器编写一些代码 它有一些大的关键常数。
#define F_CPU 16000000UL
在这种情况下,这是CPU频率。在赫兹。
实际上,如果没有在数字上手动标记光标,则很难判断是1,600,000,160,000,000还是16,000,000。
如果我在逗号#define F_CPU 16,000,000UL
中加上逗号,则会截断常量。
我使用了一些具有特定数字分隔符的深奥语言,旨在使大数字更具可读性(ex 16_000_000
,主要是用于MCU的语言)。大型“神奇数字”在嵌入式内容中相当普遍,因为它们需要描述MCU如何与现实世界对话。
C中有这样的东西吗?
答案 0 :(得分:10)
是的,C确实有预处理器分隔符:##
所以你可以写
#define F_CPU 16##000##000UL
与完全的含义与16000000UL相同。 (与16 * 1000 * 1000等其他结构不同,您需要注意不要将它们放在乘法可能导致问题的地方。)
答案 1 :(得分:6)
也许是这样的?
#define MHz(x) (1000000 * (x))
...
#define F_CPU MHz(16)
另外,我不喜欢#define
。通常最好有enum
s或常量:
static const long MHz = 1000*1000;
static const long F_CPU = 16 * MHz;
答案 2 :(得分:5)
一种可能性是这样写:
#define F_CPU (16 * 1000 * 1000)
替代地
#define MHz (1000*1000)
#define F_CPU (16 * MHz)
编辑:其他建议的MHz(x)可能更好
答案 3 :(得分:4)
您可以将常量写为计算结果(对于您的示例,16*1000*1000
)。更好的是,您可以定义另一个宏MHZ(x)
,并将常量定义为MHZ(16)
,这将使代码更加自我记录 - 代价是创建名称空间冲突概率。
答案 4 :(得分:1)
// constants.h
#define Hz 1u // 16 bits
#define kHz (1000u * Hz) // 16 bits
#define MHz (1000ul * kHz) // 32 bits
// somecode.h
#define F_CPU (16ul * MHz) // 32 bits
注意:
int
在8位MCU上为16位。答案 5 :(得分:0)
您可以使用科学记数法:
#define F_CPU 1.6e+007
或者:
#define K 1000
#define F_CPU (1.6*K*K)
答案 6 :(得分:0)
将常量定义为:
可能有助于提高可读性#define F_CPU_HZ 16000000UL
这样你就知道它里面有什么类型的数据。在我们的SW中,我们有一些外设需要设置各种预分频器,因此我们有#defines
这样:
#define SYS_CLK_MHZ (48)
#define SYS_CLK_KHZ (SYS_CLK_MHZ * 1000)
#define SYS_CLK_HZ (SYS_CLK_KHZ * 1000)
答案 7 :(得分:0)
另一个方法是在更通用的宏
中使用##预处理器运算符#define NUM_GROUPED_4ARGS(a,b,c,d) (##a##b##c##d)
#define NUM_GROUPED_3ARGS(a,b,c) (##a##b##c)
#define F_CPU NUM_GROUPED_3ARGS(16,000,000UL)
int num = NUM_GROUPED_4ARGS(-2,123,456,789); //int num = (-2123456789);
int fcpu = F_CPU; //int fcpu = (16000000UL);
这是某种所谓的WYSIWYG,但不能免于滥用。 E. g。你可能会让编译器抱怨
int num = NUM_GROUPED_4ARGS(-2,/123,456,789); //int num = (-2/123456789);
但它不会。