#define的逻辑(微芯片xc8编译器)

时间:2013-04-19 22:27:28

标签: c macros logic c-preprocessor pic

我刚刚开始学习 C 用于pic编程,我正在查看其他人的代码和编译器提供的包含文件,特别是基本的(xc.h,pic.h,pic特定的标题...)我看到了这个结构(它在pic.h中找到)

#define __delay_us(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000000.0)))

当然它有效,但我在理解它的基本逻辑时遇到了问题。 据我所知,#define是一个“别名制造者”,你告诉编译器每次在程序中遇到代码X时用Y代替。但就是这样,简单的替代。在这里,我看到一个变量,一个输入或一个参数(x),传递给替补,但我不知道如何!如果它是为了我,我会为此创建一个函数,并且我看到这样的构造有多么有用,如果我找到一个不必要的延迟宏的代码(可能是因为作者不知道本机_delay,或者因为我正在从另一个编译器移植代码)我可以简单地重新定义(假设!)“wait(200)”以指向本机“_delay(200)”。现在问题是任何人都可以向我解释这个结构是如何工作的? X甚至没有被声明,它不会被视为一个简单的替换字符,而不是一个值被传递? 这个结构是否相同?

#define wait(x) __delay_us(unsigned long x)

2 个答案:

答案 0 :(得分:2)

__delay_us(x)这里是function-like macro。类似函数的宏允许更多的动态常量(漂亮的悖论,呃)。它就像普通的宏一样工作,但你给它们一个参数。然后将该参数逐字地替换为宏,然后将其替换为代码。例如:

float y = 12000000.0;
unsigned long delay = __delay_us(y);

将被解释为:

float y = 12000000.0;
unsigned long delay = _delay((unsigned long)((y)*(_XTAL_FREQ/4000000.0)));

(注意y而不是x

在定义类似函数的宏时要非常小心:

  1. 从字面上替换参数,确保它们只在宏体中出现一次。如果有人提供函数调用作为参数,则可能会产生不必要的结果。
  2. 如您所见,根本没有进行类型检查,因为宏中不存在类型。
  3. 更多陷阱:http://gcc.gnu.org/onlinedocs/cpp/Macro-Pitfalls.html(虽然您没有使用GCC,但它可能仍适用)

答案 1 :(得分:1)

为了确保您完全理解发生了什么,我建议您尝试使用预处理器并检查其输出(在编译之前,在预处理和替换完成之后)。在GCC中,您可以看到预处理器输出:gcc -E filename