• 关于宏的一些知识


    宏(macro)本质上是文本替换,也就是在预编译的时候,会把对应的宏(常量or函数)展开替换。

    而宏根据有无参数有不同的写法

    [1]无参数(对象宏)

    #include <iostream>
    #define PI 3.14
    
    int main(void)
    {
        std::cout << PI << std::endl;
    }
    
    //预编译之后为 std::cout << 3,14 << std::endl

    [2]有参数(函数宏)

    #include <iostream>
    
    #define MIN(x,y) ((x) > (y) ? y : x)
    using namespace std;
    int main(void)
    {
        cout << MIN(5,3) << endl;
    }
    //预编译之后,就会变成 ((x) > (y)? y: x)

    注:这里里里外外加了好几层括号,是为了防止一些特殊状况的发生,比如在MIN(X, Y)前乘以某个数,由于宏本质上是文本展开,因此如果不加括号会导致一些运算顺序上的问题。

    有参数的宏还有一种情况,就是函数体比较大,一行写不下的情况,这个时候就需要用到符号""了

    #include <iostream>
    using namespace std;
    
    #define RETURN_MAX(x, y, z)   
                {   
                    int max = x;            
                    if (y > x)  max = y;  
                    if (z > x)  max = z;   
                }
    
    int main(void)
    {
        cout << MAX(5, 6, 7) <<endl;
    }
    //这样子预编译的时候就会自动替换上函数体了

    作为补充:我们经常会看到在宏函数定义中出现do { ...... } while(0)语句,这里Robert Love给出了解答:

    do{...}while(0)在C中是唯一的构造程序,让你定义的宏总是以相同的方式工作,这样不管怎么使用宏(尤其在没有用大括号包围调用宏的语句),宏后面的分号也是相同的效果

    详细的就不展开讲了,这里贴两个写得比较好的blog:

    宏定义的黑魔法 - 宏菜鸟起飞手册

    do{......} while(0)在宏定义中的作用

    差点忘了还有两个玩意儿:

    #include <iostream>
    using namespace std;
    
    #define  STRING(x) #x
    #define  PRINT(x, y) x##y
    int main(void)
    {
        cout << STRING(what the fuck) << endl;
        cout << PRINT("go", "hell") << endl;
    }
    
    //预编译之后,就变成了cout << "what the fuck" << endl
    //以及 cout << ”go hell" << endl;
    //也就是#的作用为在参数两边添加引号,##作用是连接两个参数
    原来人类的悲欢并不相通, 我只觉得他们吵闹。
  • 相关阅读:
    28. css样式中px转rem
    27.用webpack自搭react和vue框架
    26.webpack 入门
    25.redux回顾,redux中的action函数异步
    24.redux
    23.react-router 路由
    22.2、react生命周期与react脚手架(二)
    22.1 、react生命周期(一)
    21.react 组件通信
    const关键字的作用
  • 原文地址:https://www.cnblogs.com/zhlabcd/p/11276676.html
Copyright © 2020-2023  润新知