使C源中的大常量更具可读性?

时间:2012-06-11 09:15:31

标签: c embedded readability microprocessors

我正在为微处理器编写一些代码 它有一些大的关键常数。

#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中有这样的东西吗?

8 个答案:

答案 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位。
  • 只要有可能,16位字面值将被优化到8位字节(8位指令)。
  • 有符号整数文字很危险,特别是如果与按位运算符混合使用,这在嵌入式系统中很常见。默认情况下,将所有内容都设为无符号。
  • 考虑使用变量表示法或注释表明常量是32位,因为大多数8位的32位变量非常慢。

答案 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); 

但它不会。