学习 C 中的宏的建议
Posted
技术标签:
【中文标题】学习 C 中的宏的建议【英文标题】:Suggestions for learning about macros in C 【发布时间】:2011-08-08 10:11:05 【问题描述】:我参加了涵盖 C 语言的编程语言本科课程。但是,我并不是开始在嵌入式系统公司工作,而是经常在 C 语言中使用大量宏。
请分享一些链接,我可以从中了解有关宏的更多信息。
我有 K&R 2nd Ed,但我认为他们的风格过于简洁。有更多例子的东西对我来说会更好。
【问题讨论】:
浏览 linux 内核源代码树。你会从那里得到很多东西 【参考方案1】:老实说,您现在应该将宏的使用限制在非常简单的定义中。
换句话说,不要浪费时间使用宏来制作复杂的函数。
它们过去往往有三种主要用途:
预编译器使用的简单定义,例如#define USE_DEBUG
和#ifdef USE_DEBUG
。总的来说,这些在可移植代码中仍然非常有价值。
快速“内联”函数,例如#define SQR(x) ((x) * (x))
,现在更适合真正的内联函数。宏版本有很多问题,其中之一是i = 7; j = SQR(i++);
不会 一定会如你所愿。
像#define OKAY 0
、#define ERR_NOMEM 1
等预处理器枚举 - 这些最好作为真正的枚举来完成 - 因为宏版本是基本替换,您往往不会在调试信息中获得符号。
【讨论】:
我几乎没用过宏。我需要了解现有代码中已有的复杂代码。 @user714652:理解它们的最佳方法是在 SO 上将其中的三四个放在此处,以便我们解释它们。与阅读冗长的巨著相比,您将获得更快的教育。这里有人几乎是为了帮助你而摔倒在地:-) 其他一些... 多态性是宏的一个相当普遍且难以替代(无 C++)的方面。为日志记录隐式提供__FILE__
和/或__LINE__
参数是使用它们的另一个常见理由。无类型替换、字符串连接、字符串化和标识符构造是其他应用程序。【参考方案2】:
这是关于 C 预处理器的两部分教程,名为“ 来自 IAR Systems 的使用预处理的提示和技巧:
Basics of Using the Preprocessor Advanced Preprocessor Tips and Tricks【讨论】:
【参考方案3】:您可以查看以下链接:
http://www.delorie.com/gnu/docs/gcc/cpp_16.html http://www.cprogramming.com/tutorial/cpreprocessor.html您必须自己掌握大部分技巧。也许如果您可以发布一些您不理解的宏,我们可以帮助您解决这些问题。
【讨论】:
【参考方案4】:可能太明显了,但是关于 C 预处理器的 wiki 文章实际上非常好和详细:
http://en.wikipedia.org/wiki/C_preprocessor
【讨论】:
【参考方案5】:Hello,
As far as my knowledge goes the use of macro defs in embedded systems should
相当稀缺。也就是说,你应该只将它们用于:常量 定义(代码中不应出现幻数),简单内联 函数(例如返回 bool 值的函数),仅此而已。 请记住,即使内联函数为您节省了一些处理器周期, 它们通过膨胀代码和阻止对所述功能的调试来弥补。 希望这有助于并回答您的问题。
【讨论】:
【参考方案6】:使用宏非常简单:
#define MACRO_FUNCTION(par1, par2) (par1 * par2)
int product = MACRO_FUNCTION(4 ,5);
这是一个 MACRO_FUNCTION 计算产品的例子。请注意,宏没有经过类型检查。它们只是在编译时被替换。所以这取决于你使用正确的类型。
【讨论】:
它们也完全被替换了。示例#define SQUARE(x) (x * x)
然后SQUARE(a++)
将增加a
两次。
不,宏在运行时不会被替换。它们在编译时被替换,在非常早期的阶段。另请注意,由于它们是按字面意思替换的,因此使用上面的定义,MACRO_FUNCTION(x+1, y)
将产生 x+y
。
@Christopher Creutzig:你说得对,谢谢……我写的太快了。当然它们在编译时被替换以上是关于学习 C 中的宏的建议的主要内容,如果未能解决你的问题,请参考以下文章