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

在做某些事情时是否存在任何潜在的问题/危险

#define SAMPLERATE 32 // Sample rate in hertz #define ONE_MINUTE ( SAMPLERATE * 60 ) #define FIVE_MINUTES ( ONE_MINUTE * 5 ) 

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

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

int myVar = SAMPLERATE;

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

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

请确保在任何其他可能使用SAMPLERATE #define语句之前#define SAMPLERATE 32

宏不会在#define语句中扩展。 当你有#define类的时候:

 #define ONE_MINUTE ( SAMPLERATE * 60 ) 

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

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

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

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

 #include  #include  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]); }