广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C/C++细数宏与函数有那些区别
  • 728
分享到

C/C++细数宏与函数有那些区别

C++宏与函数区别C++宏与函数 2022-11-13 18:11:46 728人浏览 薄情痞子
摘要

目录一、宏和函数的对比1.宏的优点2.宏的缺点3.宏的独特性4.总结并整理宏和函数的区别5.有没有宏和函数的结合体二、宏和函数的命名约定一、宏和函数的对比 1.宏的优点 宏通常被应用

一、宏和函数的对比

1.宏的优点

  • 宏通常被应用于执行简单的运算。
  • 比如在两个数中找出较大的一个。
#define MAX(a, b) ((a)>(b)?(a):(b))

那为什么不用函数来完成这个任务?

原因有两点:

用于调用函数和从函数返回的代码可能比实际执行这个小型计算工作所需要的时间更多。

所以宏比函数在程序的规模和速度方面更胜一筹。

举例:

用宏实现两个数中找出较大值。

#define MAX(x, y) ((x) > (y) ? (x) : (y))
int main()
{
	int a = 10;
	int b = 20;
	int c = MAX(a, b); // 宏
	return 0;
}

转到反汇编,查看汇编代码。

    int c = MAX(a, b); // 宏
00791783  mov         eax,dWord ptr [a]  
00791786  cmp         eax,dword ptr [b]  
00791789  jle         __$EncStackInitStart+3Ah (0791796h)  
0079178B  mov         ecx,dword ptr [a]  
0079178E  mov         dword ptr [ebp-0E8h],ecx  
00791794  jmp         __$EncStackInitStart+43h (079179Fh)  
00791796  mov         edx,dword ptr [b]  
00791799  mov         dword ptr [ebp-0E8h],edx  
0079179F  mov         eax,dword ptr [ebp-0E8h]  
007917A5  mov         dword ptr [c],eax

用函数实现两个数中找出较大值。

int Max(int x, int y)
{
	return ((x) > (y) ? (x) : (y));
}
int main()
{
	int a = 10;
	int b = 20;
	int c = Max(a, b); // 函数
	return 0;
}

调用函数的汇编代码。

    int c = Max(a, b); // 函数
002C1793  mov         eax,dword ptr [b]  
002C1796  push        eax  
002C1797  mov         ecx,dword ptr [a]  
002C179A  push        ecx  
002C179B  call        _Max (02C139Dh)  // 调用Max函数
002C17A0  add         esp,8  
002C17A3  mov         dword ptr [c],eax  

计算的汇编代码。

int Max(int x, int y)
{
002C1DF0  push        ebp  
002C1DF1  mov         ebp,esp  
002C1DF3  sub         esp,0C4h  
002C1DF9  push        ebx  
002C1DFA  push        esi  
002C1DFB  push        edi  
002C1DFC  lea         edi,[ebp-4]  
002C1DFF  mov         ecx,1  
002C1E04  mov         eax,0CCCCCCCCh  
002C1E09  rep stos    dword ptr es:[edi]  
002C1E0B  mov         ecx,offset _66EADA86_详解预处理\test@c (02CC000h)  
002C1E10  call        @__CheckForDebuggerJustMyCode@4 (02C1307h)  
// 下面这些才是计算的代码,上面这些代码可以说还是在为调用函数做准备
// 并且可以看出下面的汇编代码和宏那里的汇编代码是一样的
    return ((x) > (y) ? (x) : (y));
002C1E15  mov         eax,dword ptr [x]  
002C1E18  cmp         eax,dword ptr [y]  
002C1E1B  jle         __$EncStackInitStart+2Ch (02C1E28h)  
002C1E1D  mov         ecx,dword ptr [x]  
002C1E20  mov         dword ptr [ebp-0C4h],ecx  
002C1E26  jmp         __$EncStackInitStart+35h (02C1E31h)  
002C1E28  mov         edx,dword ptr [y]  
002C1E2B  mov         dword ptr [ebp-0C4h],edx  
002C1E31  mov         eax,dword ptr [ebp-0C4h]  
}

函数返回的汇编代码。

002C1E37  pop         edi  
002C1E38  pop         esi  
002C1E39  pop         ebx  
002C1E3A  add         esp,0C4h  
002C1E40  cmp         ebp,esp  
002C1E42  call        __RTC_CheckEsp (02C1230h)  
002C1E47  mov         esp,ebp  
002C1E49  pop         ebp  
002C1E4A  ret

总结:

如果用函数的话,会经过以下几个步骤:

  • 函数调用。
  • 计算。
  • 函数返回。

根据上面的汇编代码可以看出,函数调用和函数返回所用的汇编指令远多于计算所用的汇编指令,这就导致函数调用和返回所用的时间远多于计算所用的时间。而宏本质是替换,不用进行函数调用和返回,所以这就是宏在实现小型计算工作时比函数快的原因。

  • 更为重要的是函数的参数必须声明为特定的类型。

所以函数只能在类型合适的表达式上使用。

而宏是类型无关的,宏可以适用于整形、长整型、浮点型等,可以用于 “>” 来比较的类型。

举例:

下面为宏和函数实现的两个数中找出较大值。

// 宏
#define MAX(x, y) ((x) > (y) ? (x) : (y))
// 函数
int Max(int x, int y)
{
	return ((x) > (y) ? (x) : (y));
}

可以看出,该函数只能对两个int类型的数进行比较,而宏却可以对两个任意类型的数进行比较,这就使宏用起来更加的灵活。

2.宏的缺点

  1. 每次使用宏的时候,一份宏定义的代码将插入到程序中。除非宏比较短,否则可能大幅度增加程序的长度。
  2. 宏是没法调试的。
  3. 宏由于类型无关,也就不够严谨。
  4. 宏可能会带来运算符优先级的问题,导致程容易出现错。

3.宏的独特性

宏有时候可以做函数做不到的事情。

比如:宏的参数可以出现类型,但是函数做不到。

#define MALLOC(num, type) (type*)malloc(num * sizeof(type))
int main()
{
	// 使用
	int* p1 = MALLOC(10, int); // 替换后为 int* p1 = (int*)malloc(10 * sizeof(int));
	char* p2 = MALLOC(5, int); // 替换后为 int* p2 = (char*)malloc(5 * sizeof(char));
	return 0;
}

4.总结并整理宏和函数的区别

属 性#define定义宏函数
代 码 长 度每次使用时,宏代码都会被 插入到程序中。除了非常小的宏之外,程序的长度会大幅度增长函数代码只出现于一个地方;每次使用这个函数时,都调用那个地方的同一份代码
执 行 速 度更快存在函数的调用和返回的额外开销,所以相对慢一些
操 作 符 优 先 级宏参数的求值是在所有周围表达式的上下文环境里,除非加上括号,否则邻近操作符的优先级可能会产生不可预料的后果,所以建议宏在书写的时候多些括号。函数参数只在函数调用的时候求值一次,它的结果值传递给函数。表达式的求值结果更容易预 测。
带 有 副 作 用 的 参 数参数可能被替换到宏体中的多个位置,所以带有副作用的参数求值可能会产生不可预料的结果。函数参数只在传参的时候求值一 次,结果更容易控制。
参 数 类 型宏的参数与类型无关,只要对参数的操作是合法的, 它就可以使用于任何参数类型。函数的参数是与类型有关的,如果参数的类型不同,就需要不同的函数,即使他们执行的任务是 不同的。
调 试宏是不方便调试的函数是可以逐语句调试的
递 归宏是不能递归函数是可以递归的

5.有没有宏和函数的结合体

答案是当然有。

在C99和c++里面都有一个东西叫做内联函数(inline)

内联函数既有函数的优点又有宏的优点:

  • 宏的优点:内联函数没有函数的调用和返回。
  • 函数的优点: 内联函数本身是个函数,它没有参数优先级、副作用等宏的缺点。

提示:由于本篇文章主要是讲宏和函数的区别,内联函数就不多讲,这里只做了解,后面我会单独写一篇文章来讲解内联函数的。

二、宏和函数的命名约定

一般来讲函数的宏的使用语法很相似。所以语言本身没法帮我们区分二者。

那么我们平时就应该有一个良好的书写习惯:

把宏名全部大写

函数名不要全部大写

这里可以参考《高质量C/C++编程指南》这本书,有兴趣的小伙伴可以去看看。

到此这篇关于C/C++细数宏与函数有那些区别的文章就介绍到这了,更多相关C/C++宏与函数内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: C/C++细数宏与函数有那些区别

本文链接: https://www.lsjlt.com/news/170192.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C/C++细数宏与函数有那些区别
    目录一、宏和函数的对比1.宏的优点2.宏的缺点3.宏的独特性4.总结并整理宏和函数的区别5.有没有宏和函数的结合体二、宏和函数的命名约定一、宏和函数的对比 1.宏的优点 宏通常被应用...
    99+
    2022-11-13
    C++宏与函数区别 C++宏与函数
  • c++内联函数和宏函数有什么区别
    C++内联函数和宏函数都可以在编译时进行函数体的替换,但是它们有以下几点区别:1. 编译时间点:宏函数在预处理阶段被展开,而内联函数...
    99+
    2023-10-19
    c++
  • C语言中宏和函数的区别有哪些
    这篇文章主要介绍了C语言中宏和函数的区别有哪些的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇C语言中宏和函数的区别有哪些文章都会有所收获,下面我们一起来看看吧。C语言中的宏和函数是非常相似的,它们都可以完成类似...
    99+
    2023-07-05
  • C++中虚函数与纯虚函数的区别有哪些
    小编给大家分享一下C++中虚函数与纯虚函数的区别有哪些,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!什么是虚函数:虚函数 是在基类中使用关键字 virtual 声...
    99+
    2023-06-20
  • C语言中宏和函数的9个区别详解
    目录1.代码长度2.执行速度3.操作符优先级4.带有副作用的参数5.参数类型6.调试7.递归8.命名约定9.其他总结C语言中的宏和函数是非常相似的,它们都可以完成类似的功能。比如,想...
    99+
    2023-05-14
    C语言 函数区别 C语言 函数 C语言 C语言 函数
  • C语言函数与宏怎么使用
    这篇文章主要讲解了“C语言函数与宏怎么使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C语言函数与宏怎么使用”吧!一、函数与宏宏是由预处理器直接替换展开的,编译器不知道宏的存在函数是由编译...
    99+
    2023-06-30
  • C++ 虚函数与纯虚函数的使用与区别
    目录什么是虚函数:虚函数的注意事项:纯虚函数纯虚函数的注意事项:虚函数与纯虚函数区别什么是虚函数: 虚函数 是在基类中使用关键字 virtual 声明的函数,在C++ 语言中虚函数...
    99+
    2022-11-12
  • C++详细讲解函数调用与Struct和CLass的区别
    目录一、结构回顾1、传值调用2、引用调用3、指针调用二、public和private权限修饰符三、类简介四、类的组织一、结构回顾 结构:自定义的数据类型,不管C++/C结构都用Str...
    99+
    2022-11-13
  • C++中成员函数和友元函数有哪些区别
    小编给大家分享一下C++中成员函数和友元函数有哪些区别,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!为什么使用成员函数和友元函数这个问题至关重要,直接影响着后面的...
    99+
    2023-06-29
  • C++中成员函数和友元函数的区别有哪些
    C++中成员函数和友元函数之间有以下几点区别:1. 访问权限:成员函数可以直接访问类的私有成员和保护成员,而友元函数可以在类的外部访...
    99+
    2023-08-16
    C++
  • C语言中函数宏封装的方式有哪些
    本篇内容介绍了“C语言中函数宏封装的方式有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1. 函数宏介绍函数宏,即包含多条语句的宏定义,...
    99+
    2023-07-05
  • C语言中的内联函数(inline)与宏定义(#define)详细解析
    先简明扼要,说下关键:1、内联函数在可读性方面与函数是相同的,而在编译时是将函数直接嵌入调用程序的主体,省去了调用/返回指令,这样在运行时速度更快。2、内联函数可以调试,而宏定义是不...
    99+
    2022-11-15
    内联函数 宏定义
  • R语言中c()函数与paste()函数的区别说明
    c()函数:将括号中的元素连接起来,并不创建向量 paste()函数:连接括号中的元素 例如 c(1, 2:4),结果为1 2 3 4 paste(1, 2:4),结果为“1 2” ...
    99+
    2022-11-12
  • Python与c++的区别有哪些
    Python与c++的区别有:1、C++要比Python的运行效率高,在运行代码时都会变成CPU指令来执行,但Python转换出来的CPU指令比C++多;2、Python的开发效率比C++更快,Python简单易学、适合新手操作;3、Pyt...
    99+
    2022-10-10
  • C语言深入分析函数与宏的使用
    目录一、函数与宏二、宏的妙用三、小结一、函数与宏 宏是由预处理器直接替换展开的,编译器不知道宏的存在函数是由编译器直接编译的实体,调用行为由编译器决定多次使用宏会导致最终可执行程序的...
    99+
    2022-11-13
  • 详解C语言中strcpy函数与memcpy函数的区别与实现
    目录字符串拷贝函数(strcpy)函数原型应用实例缺点内存拷贝函数(memcpy)函数原型应用实例memcpy的模拟实现(my_memcpy)实现样例具体实现字符串拷贝函数(strc...
    99+
    2022-12-29
    C语言 strcpy memcpy区别 C语言 strcpy memcpy实现 C语言 strcpy memcpy
  • 浅析Python与Java和C之间有哪些细微区别
    目录1.变量是什么(1)C认为变量应该是容器(2)Python认为变量应该是标签(3)Java认为我们不应该关心这个问题2.循环与迭代(1)传统的循环(2)继承与发展(3)新的问题3...
    99+
    2022-11-11
  • c++ 内联函数和普通函数的区别
    前言 内联函数是c++为了提高程序的运行速度做的改进,它与普通函数区别在于: 编译器如何将它们组合到程序中。所以我们需要深入到程序内部。 我们的最终的可执行程序由 一组机器指令组成...
    99+
    2022-11-12
  • cin.getline()和getline()函数在C++中有什么区别
    本篇文章为大家展示了cin.getline()和getline()函数在C++中有什么区别,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。cin.getline():用法:接收一个字符串,可以接收空格...
    99+
    2023-06-14
  • java与c语言的区别有哪些?
    java与c语言的区别有哪些?1、Java与C内存分配不同:Java中内存分配五个区,分别为栈区(存储的是局部变量,使用完毕,立即回收),堆区(存储的是new出来的东西,实体,对象,每一个对象都有地址值,每个对象的数据都有默认值,使用完毕后...
    99+
    2020-10-28
    java教程 java c语言
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作