• Cpp知识点系列-宏定义


    前言

    一句话,宏定义就是全局替换和声明的一种方式!

    我原本以为没必要详细了解,后来发现做错了题,纠结之后还是整理一下好了。

    宏定义

    掌握"宏"概念的关键是“”。一切以换为前提、做任何事情之前先要换!

    不含参

    #define PI 3.1415926
    

    把程序中出现的PI全部换成3.1415926

    #define endl '\n'
    

    把程序中出现的endl全部换成字符'\n'

    含参

    例子1

    1. #include<iostream>
    2. #define endl '\n'
    3. #define SR(x, y) x+y
    4. using namespace std;
    5. void sum1() {
    6.     int a = 5, b = 4;
    7.     a += 2 * SR1(a, b);
    8.     cout << "sum1=" << a << endl;//结果是19
    9. }

    第一步,先换:语句替换后成为a+=2*a+b

    第二步,替换变量,语句替换后成为5+=2*5+4

    第三步,计算式子,先是右侧公式计算结果为14,此时为5+=14;最后赋值到变量上,结果是19

    例子2

    1. #include<iostream>
    2. #define endl '\n'
    3. #define SR(x, y) ((x)+(y))
    4. using namespace std;
    5. void sum2() {
    6.     int a = 5, b = 4;
    7.     a += 2 * SR2(a, b);
    8.     cout << "sum2=" << a << endl;//结果是23
    9. }

    第一步,先换:语句替换后成为a+=2*((a)+(b))

    第二步,替换变量,语句替换后成为5+=2*(5+4)

    第三步,计算式子,先是右侧公式计算结果为18,此时为5+=18;最后赋值到变量上,结果是23

    例子3

    1. #define fun1(a) a
    2. void f1() {
    3.     cout << "f1=" << fun1(12 + 3)<< endl;//结果是数字15
    4. }
    5. #define fun2(a) "a"
    6. void f2() {
    7.     cout << "f2=" << fun2(12 + 3)<< endl;//结果是字符串a
    8. }

    请看清楚,定义的后面究竟是参数本身还是带着双引号的字符串!

    含参循环

    1. #include <iostream>
    2. using namespace std;
    3. // #define doit(m, n) for(int i=0;i<(n);++i){m+=i;}
    4. #define doit(m,n) for(int i=0;i<(n);++i)\
    5. {\
    6. m+=i;\
    7. }
    8. int main() {
    9.     int a = 5, b = 4;
    10.     doit(a, b);
    11.     cout << a;// 结果为11
    12.     return 0;
    13. }

    宏定义也是可以分行的!!!

    宏定义也是可以运行循环的!!!

    宏定义也是能让人栽跟头的!!!

    宏定义语法特点

    ###

    • 使用#把宏参数变为一个字符串

    • ##把两个宏参数贴合在一起

    1. #include<iostream>
    2. using namespace std;
    3. #define endl '\n'
    4. #define STR(s)     #s
    5. #define CONS(a, b)  int(a##e##b)
    6. int main() {
    7.     cout << STR(vck)<< endl;       // 输出字符串"vck"
    8.     cout << CONS(23);  // 2e3 输出:2000
    9.     return 0;
    10. }
    11. #undef CONS
    12. #undef STR

    其实照我现在的理解,有这种复杂需求的话还是写成函数更合适一些。

    单纯为了炫技的话,当我没说……

    更多详细应用还是参考原文博客吧,传送门在文末。

    特点

    1. 宏定义末尾不加分号

    2. 宏定义写在函数的花括号外边,作用域为其后的程序,可以用#undef命令终止作用域

    3. 宏定义可以嵌套

    4. 字符串""中永远不包含宏

    5. 宏定义不分配内存,想要分配内存去使用变量吧。

    6. 预处理不做语法检查。因为预处理是在编译之前的处理,而编译工作的任务之一就是语法检查

    7. 宏定义不做计算,只作替换

    8. 宏的哑实结合不存在类型,也没有类型转换。

    优点

    使用宏可提高程序的通用性和易读性,减少不一致性,减少输入错误和便于修改。

    例如:数组大小常用宏定义。

    与函数的区别

      • 函数调用是在编译后程序运行时进行,并且分配内存。

      • 宏替换在编译前进行,不分配内存

      • 函数一般只有一个返回值,特殊情况下用pair也是一个对象,对象内两个值

      • 宏则可以设法得到多个值

    1. 宏展开会使源程序变长,函数调用不会

      • 函数调用占运行时间(分配内存、保留现场、值传递、返回值)

      • 宏展开不占运行时间,只占编译时间

    感谢

    源文件:

    gitee:https://gitee.com/JunKuangKuang/KeenCPPTest-all/tree/main/basic/define

    github.com:https://github.com/JunKuangKuang/KeenCPPTest-all/blob/main/basic/define

    感谢现在的好奇,为了能成为更好的自己。

    王珂的个人笔记

     

  • 相关阅读:
    实现并发新高度:23ai的无锁列值保留
    【mysql篇-基础篇】通用语法2
    Python自动查重之原理、方法与实践详解
    LeetCode315 周赛
    在互联网上做好这两件事,轻松年赚50w?
    SPRINGBOOT03_自动配置原理入门、Lombok、dev-tools、快速初始化boot项目
    港联证券:三季报亮相 盈利拐点来了?
    JVM 别和我说你还不知道这几种垃圾回收器?Serial |Parallel|ParNew|CMS|G1|ZGC
    BI如何实现用户身份集成自定义安全程序开发
    Postgresql中VACUUM操作原理和应用
  • 原文地址:https://blog.csdn.net/qq_41461536/article/details/127737082