C中的宏和函数有什么区别?

C中的宏和函数有什么区别?,c,function,macros,c-preprocessor,C,Function,Macros,C Preprocessor,宏和C中的函数有什么区别?请告诉我一个可以使用宏和函数的应用程序?基本区别在于函数是编译的,宏是预处理的。当您使用函数调用时,它将转换为ASM调用,并使用所有这些堆栈操作来传递参数和返回值。使用宏时,C预处理器将使用宏转换所有字符串,然后编译 使用宏的缺点是它们隐藏了实现。如果你有一个bug,就很难找到它。你必须把宏当作一个文本替换:就像你每次在代码中看到宏时都内联宏代码一样。这对“代码片段”很有好处,因为您避免了函数调用开销,因为每次调用函数时,您都会努力将参数推送到堆栈上。另一个区别是,函数

宏和C中的函数有什么区别?请告诉我一个可以使用宏和函数的应用程序?

基本区别在于函数是编译的,宏是预处理的。当您使用函数调用时,它将转换为ASM调用,并使用所有这些堆栈操作来传递参数和返回值。使用宏时,C预处理器将使用宏转换所有字符串,然后编译


使用宏的缺点是它们隐藏了实现。如果你有一个bug,就很难找到它。

你必须把宏当作一个文本替换:就像你每次在代码中看到宏时都内联宏代码一样。这对“代码片段”很有好处,因为您避免了函数调用开销,因为每次调用函数时,您都会努力将参数推送到堆栈上。

另一个区别是,函数中有堆栈开销,但宏中没有堆栈开销;它只是代码的扩展。

在C(和C++)中,宏是一个预处理器指令。这意味着在您的程序开始编译之前,它将遍历并处理所有宏。宏很有用,因为

  • 它们可以使你的程序更容易阅读
  • 它们可以提高效率(因为它们可以在编译时计算)
  • 它们可以缩短经常使用的长的或复杂的表达式。例如,我们使用一个宏来获取当前的log4cpp记录器,并使用另外几个宏以不同的级别对其进行写入
缺陷

  • 扩展可执行文件的大小
  • 如果不小心的话,你的名字会被淹没。例如,如果您有太多的预处理器宏,您可能会在代码中意外地使用它们的名称,这可能会使调试非常混乱
范例

#define INCREMENT(x) x++
函数是一段可以相对独立地执行和执行特定任务的代码。你可以把它想象成一个数学函数:给定一组输入的函数将给出一个特定的输出。在C中,这些定义为

<return type> <name>(<parameters>)
{
  //code body
}
()
{
//代码体
}

函数是一种从值到值的操作,即通常认为程序在操作的数据类型(数字、字符串等)

宏是从一个代码到另一个代码的操作。它获取程序的一部分,并使用它为程序生成不同的部分

C中的函数和宏之间完全没有重叠;他们不会做同样的事情。(您无法将函数从值写入代码;尽管表面上看,您无法将宏从代码写入值。我知道这看起来是可以的,但重要的是要理解这不是您实际正在做的。)

宏可以看起来像函数,因为您可以编写一个宏来处理一段代码,该代码本身生成或表示一个值,但该宏仍然没有对该值本身进行操作:它将生成值的代码(可能是一个简单的数字)编织成值消耗代码(这看起来像是宏的“主体”)。这意味着使用类似宏的函数非常容易混淆,而不是它们的最佳用途。相反,函数实际上是一个单独的离散代码块


函数通常在运行时运行,而宏(在C中)总是在编译时运行,这只是一个限制,因为值通常是动态的,代码通常在运行时不可用。这实际上不是函数或宏的基本方面(函数可以内联和优化;宏可以应用于动态生成的代码),这有点像是在转移注意力。

宏的优点是,我们只定义一次,如果我们想更改值,我们只能在一个地方进行更改,而值会在整个程序中反映出来。

这是您要求更改的唯一原因“一个可以使用宏和函数的应用程序"这是因为这是家庭作业。为什么不自己动手做呢?是的,内联函数在这方面更好。如果函数是内联的,就不会有堆栈开销。这个答案非常混乱。它让人困惑,而不是启发。@JohnKugelman好吧,有什么让人困惑的?我怎么能让你更清楚呢?看起来很简单转发给我足够多,否则我就不会那样写了,这在技术上是正确的,这比这个问题的一些现有答案更准确。是的,是的,当然这是一个老问题,在我写这个答案时没有看到,抱歉。它仍然为问题提供了不同的材料。答案集中在编译上-时间/运行时或机器代码/文本是错误的,它们描述了一个实现,但没有抓住要点。(a)函数不是严格意义上的从值到值的操作;这是一个数学定义。函数有副作用,它们不仅仅是映射。而且它们不需要返回值。(b)说宏是“从代码到代码的操作”是一种令人困惑的描述宏的方式。我会用文本替换的方式来解释宏函数和类似函数的宏之间存在巨大的重叠。声称它们在用途上不重叠真的很奇怪。宏的一个主要用途是强制内联代码,否则这些代码会进入函数中。函数和类似函数的宏之间在用途上没有重叠,我支持这一点。在用法上存在重叠(这个问题的存在是显而易见的),但它们做的不是同一件事。宏永远不可能接受2和2并产生4,它只能接受
2
2
并产生
2+2
。这是核心区别。其他一切都是附带的/实现细节/特定于C文化。相反,建议宏和中的任何关系衬里就是这样一个例子