美文网首页
对宏的简单认识和使用

对宏的简单认识和使用

作者: 永远保持一颗进取心 | 来源:发表于2017-07-10 09:26 被阅读9次

    参考文章:https://onevcat.com/2014/01/black-magic-in-macro/
    http://www.cnblogs.com/alexshi/archive/2012/03/09/2388453.html
    https://zhidao.baidu.com/question/425382312987430932.html

    宏分为两类

    • 对象宏(object-like macro)

    • 函数宏(function-like macro)

    对象宏

    对象宏相对比较简单,一般是用来定义一些常数:

    #define M_PI 3.14159265358979323846264338
    

    编译时,编译器会在语义分析认定是宏,会将 M_PI 替换为具体的圆周率数字,这个过程称为宏的展开。

    函数宏

    函数宏,意味着它的行为类似于函数;它可以接受参数。只要在宏名称(上面例子中的 M_PI 就是宏名称)的后面加上括号,就成为函数宏。

    #define MIN(A, B) (A < B ? A : B)
    

    这是一个比较两个数大小的宏,A和B 是宏可以接受的两个参数,宏展开时,它们会分别代入宏体中的 A和B。宏体用括号括起来是要防止宏展开时不如预期,例如

    我要输出两个数字中较小数字的10倍:
    
    #define MIN(A, B) A < B ? A : B
    int a = 100;
    int b = 200;
    NSLog(@"smaller: %d", 10*MIN(a, b));
    

    输出则为 200,跟预期的1000不一样。因为宏展开后是这样的

    10 * a < b ? a : b
    

    先做了乘法,再进行比较。所以不管是对象宏还是函数宏,这点都要注意。

    关于#和##、__VA_ARGS__

    # 运算符可以将宏的参数转化为字符串字面量,它仅仅出现在函数宏中。
    使用方法

    #define LOG(A, B) NSLog(@""#A" = %d, "#B" = %d" , A, B)
     
    int main(int argc, char *argv[]) {
        @autoreleasepool {
            int a = 100;
            int b = 200;
            LOG(a, b);
        }
    }
    
    输出为: a = 100, b = 200
    

    ## 运算符可以将两个标识符粘合在一起。如

    #define GLUE(A, B) A##B
     
    int main(int argc, char *argv[]) {
        @autoreleasepool {
            int a = 100;
            int b = 200;
            int ab = 300;
            NSLog(@"%d", GLUE(a, b));
        }
    }
    
    输出:300
    

    __VA_ARGS__

    在一些宏参数中会出现 ‘...’,‘...’ 指的是可变参数,意思是可以接受零个或者是多个参数。而在宏体里,对应的便是 __VA_ARGS__ ,例

    #define WHLOG(fmt, ...) NSLog(fmt,__VA_ARGS__)
    int main(int argc, char *argv[]) {
        @autoreleasepool {
            int a = 100;
            WHLOG(@"Hello world %d", a);
        }
    }
    
    输出为:Hello world 100
    

    但是这里有个问题:当对 ‘...’ 输入零个参数的时候,当展开宏的时候会多了一个逗号出来,这时候编译会不通过。针对这个问题,可以用 ##__VA_ARGS__ 这个代替 __VA_ARGS__ ;当输入零个参数的时候,预处理器会把多出它之前多出的那个逗号去掉。

    相关文章

      网友评论

          本文标题:对宏的简单认识和使用

          本文链接:https://www.haomeiwen.com/subject/pakyhxtx.html