1

我刚开始学习用于 pic 编程的C语言,我正在查看其他人的代码以及编译器提供的包含文件,尤其是基本文件(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)
4

2 回答 2

3

__delay_us(x)这是一个类似函数的宏。类似函数的宏允许更多的动态常量(很好的悖论,嗯)。它就像一个普通的宏一样工作,但是你给他们一个参数。然后将参数逐字替换为宏,然后将其替换为代码。例如:

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. 如您所见,根本没有进行类型检查,因为宏中不存在类型。

更多陷阱: http: //gcc.gnu.org/onlinedocs/cpp/Macro-Pitfalls.html(虽然你没有使用GCC,它可能仍然适用)

于 2013-04-19T22:44:18.177 回答
1

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

于 2013-04-19T22:54:46.440 回答