最新公告
  • 欢迎您光临源码库,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入
  • 【C/C++内功心法】详解宏和函数的区别

    文章目录

    前言

    一、宏和函数的对比

    1.宏的优点

    2.宏的缺点

    3.宏的独特性

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

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

    二、宏和函数的命名约定

    总结

    大家好啊,我是不一样的烟火a,今天我将会为大家讲解面试中常被问到的问题——宏和函数的区别。本篇文章对基础薄弱的小伙伴十分友好,相信只要看完一定能收获满满。

    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.宏的缺点

    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.总结并整理宏和函数的区别

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

    答案是当然有。

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

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

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

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

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

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

    • 把宏名全部大写
    • 函数名不要全部大写
    • 这里可以参考《高质量C/C++编程指南》这本书,有兴趣的小伙伴可以去看看。

    以上就是宏和函数区别的所有内容了,并且都是高频考点,所以大家一定要牢记于心。如果大家有什么解决不了的问题,欢迎大家评论区留言或者私信告诉我。如果感觉对自己有用的话,可以点个赞或关注鼓励一下博主,我会越做越好的,感谢各位的支持。

    原文链接:https://blog.csdn.net/qq_64042727/article/details/127327644

    1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
    2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
    3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
    4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
    5. 如有链接无法下载、失效或广告,请联系管理员处理!
    6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!

    源码资源库 » 【C/C++内功心法】详解宏和函数的区别