在C中的新#define中使用先前定义的#define

时间:2014-01-09 20:05:08

标签: c c-preprocessor

在执行

等操作时是否存在任何潜在的问题/危险
#define SAMPLERATE 32 // Sample rate in hertz
#define ONE_MINUTE ( SAMPLERATE * 60 )
#define FIVE_MINUTES ( ONE_MINUTE * 5 ) 

我的编译器不会发出任何错误或警告。这非常好,因为我可以更改一个#define值(SAMPLERATE),而其他所有值都设置为他们需要的值而没有其他更改。我不完全确定这是最佳做法还是安全。

3 个答案:

答案 0 :(得分:7)

宏不会在#define语句中展开。当您有#define时:

#define ONE_MINUTE ( SAMPLERATE * 60 )

它定义了扩展(正文)为ONE_MINUTE的宏( SAMPLERATE * 60 )。是否在您的程序中的其他地方定义了一个名为SAMPLERATE的宏是完全不相关的。这种宏的存在(或不存在)没有效果。

相反,当使用宏(并扩展宏)时,将重新扫描该扩展的结果,以便扩展其他宏。所有重要的是SAMPLERATE是否在ONE_MINUTE被使用的位置定义。

答案 1 :(得分:6)

预处理器处理#define。预处理器在编译之前运行,可以执行简单的数学运算和代码的复制/粘贴。例如,您可以使用您的示例执行以下操作:

int myVar = SAMPLERATE;

在编译之前,预处理器只需将32粘贴到SAMPLERATE

这个机制很强大,因为您现在已经为整数值创建了一个名称。这为您和未来的开发人员增加了意义。它还允许您在一个地方而不是许多地方进行更改。

请确保#define SAMPLERATE 32在使用#define的任何其他SAMPLERATE语句之前{/ 1}}。

答案 2 :(得分:0)

预处理器使用#define常量(类似对象的宏)来将标识符替换为指定的令牌列表。 #defines也可以参数。这些被称为类似函数的宏。这种宏的优点是它们可以在线替换,而这些功能并不能保证正常功能。在条件编译中经常使用类似对象的宏。我认为宏的缺点是它们不是类型安全的。小心使用时,它们可以提供很大的帮助。

这是一个让您的生活更轻松的宏的例子。

#include <stdio.h>
#include <stdlib.h>

static const unsigned char BYTES[256] = {
#define A(n) n, n+1, n+1, n+2
#define B(n) A(n), A(n+1), A(n+1), A(n+2)
#define C(n) B(n), B(n+1), B(n+1), B(n+2)
C(0), C(1), C(1), C(2)
};

int main() {
  unsigned char BYTE = 0b01011101;
  printf("The byte 01011101 has %d set bits.\n",BYTES[BYTE]);
}