C 宏有什么用? [英] What are C macros useful for?

查看:28
本文介绍了C 宏有什么用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了一点 C 语言,我可以很好地阅读它以大致了解它在做什么,但是每次我遇到一个宏时,它都让我彻底崩溃.我最终不得不记住宏是什么,并在阅读时将其替换在脑海中.我遇到的那些直观易懂的总是像迷你函数一样,所以我一直想知道为什么它们不只是函数.

I have written a little bit of C, and I can read it well enough to get a general idea of what it is doing, but every time I have encountered a macro it has thrown me completely. I end up having to remember what the macro is and substitute it in my head as I read. The ones that I have encountered that were intuitive and easy to understand were always like little mini functions, so I always wondered why they weren't just functions.

我可以理解需要在预处理器中为调试或跨平台构建定义不同的构建类型,但定义任意替换的能力似乎只会使已经很难理解的语言变得更加难以理解.

I can understand the need to define different build types for debug or cross platform builds in the preprocessor but the ability to define arbitrary substitutions seems to be useful only to make an already difficult language even more difficult to understand.

为什么要为 C 引入如此复杂的预处理器?有没有人有一个使用它的例子,让我明白为什么它似乎仍然用于#debug 样式条件编译以外的其他目的?

Why was such a complex preprocessor introduced for C? And does anyone have an example of using it that will make me understand why it still seems to be used for purposes other than simple if #debug style conditional compilations?

阅读了许多答案,我仍然不明白.最常见的答案是内联代码.如果 inline 关键字不这样做,那么要么它有充分的理由不这样做,要么实现需要修复.我不明白为什么需要一种完全不同的机制,这意味着真正内联这段代码"(除了在内联之前编写的代码之外).我也不理解提到的如果它太愚蠢而不能放入函数中"的想法.当然,任何接受输入并产生输出的代码都最好放在函数中.我想我可能没有得到它,因为我不习惯编写 C 的微优化,但预处理器感觉就像是一些简单问题的复杂解决方案.

Having read a number of answers I still just don't get it. The most common answer is to inline code. If the inline keyword doesn't do it then either it has a good reason to not do it, or the implementation needs fixing. I don't understand why a whole different mechanism is needed that means "really inline this code" (aside form the code being written before inline was around). I also don't understand the idea that was mentioned that "if its too silly to be put in a function". Surely any piece of code that takes an input and produces an output is best put in a function. I think I may not be getting it because I am not used to the micro optimisations of writing C, but the preprocessor just feels like a complex solution to a few simple problems.

推荐答案

我最终不得不记住宏是什么,并在阅读时将其替换在脑海中.

I end up having to remember what the macro is and substitute it in my head as I read.

这似乎对宏的命名反映不佳.如果它是一个 log_function_entry() 宏,我会假设你不必模拟预处理器.

That seems to reflect poorly on the naming of the macros. I would assume you wouldn't have to emulate the preprocessor if it were a log_function_entry() macro.

我遇到的那些直观易懂的总是像小迷你函数,所以我一直想知道为什么它们不只是函数.

The ones that I have encountered that were intuitive and easy to understand were always like little mini functions, so I always wondered why they weren't just functions.

通常它们应该是,除非它们需要对泛型参数进行操作.

Usually they should be, unless they need to operate on generic parameters.

#define max(a,b) ((a)<(b)?(b):(a))

将适用于带有 < 运算符的任何类型.

will work on any type with an < operator.

不仅仅是函数,宏允许您使用源文件中的符号执行操作.这意味着您可以创建一个新的变量名称,或引用宏所在的源文件和行号.

More that just functions, macros let you perform operations using the symbols in the source file. That means you can create a new variable name, or reference the source file and line number the macro is on.

在 C99 中,宏还允许您调用可变参数函数,例如 printf

In C99, macros also allow you to call variadic functions such as printf

#define log_message(guard,format,...) 
   if (guard) printf("%s:%d: " format "
", __FILE__, __LINE__,__VA_ARGS_);

log_message( foo == 7, "x %d", x)

其中的格式类似于 printf.如果守卫为真,它会输出消息以及打印消息的文件和行号.如果它是一个函数调用,它不会知道你从中调用它的文件和行,并且使用 vaprintf 会有点更多的工作.

In which the format works like printf. If the guard is true, it outputs the message along with the file and line number that printed the message. If it was a function call, it would not know the file and line you called it from, and using a vaprintf would be a bit more work.

这篇关于C 宏有什么用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆