在执行
等操作时是否存在任何潜在的问题/危险#define SAMPLERATE 32 // Sample rate in hertz
#define ONE_MINUTE ( SAMPLERATE * 60 )
#define FIVE_MINUTES ( ONE_MINUTE * 5 )
我的编译器不会发出任何错误或警告。这非常好,因为我可以更改一个#define
值(SAMPLERATE),而其他所有值都设置为他们需要的值而没有其他更改。我不完全确定这是最佳做法还是安全。
答案 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]);
}