zoukankan      html  css  js  c++  java
  • [C] 宏的一些高级用法

    前言

        非常感谢monkey_zx整理的#define命令的一些高级使用,本文主要对他的这篇文章做些补充,加深对部分宏的原理和用法的理解。

    特殊符号

    (1)#,表示将跟在它之后的参数转换为字符串。

         例子:

    #define STR(x)  #x

         如:STR(amigo)等价"amigo"。

    (2)##,表示先分隔,然后强制连接前后两个参数。

         例子:

    #define VAR_NAME(type, name)    type type##_##name
    #define VAR_NAME1(type, name)   type type##_name##name

         如:

         VAR_NAME(int, a)等价于「int int_a」(即定义名为int_a的int变量)。先分隔成type、_、name,之后替换,最后再连接起来。

         VAR_NAME1(int, b)等价于“「int int_nameb」”。先分隔成type、_name(这里面的name之后是不会被替换的)、name,之后替换,最后在连接起来。

    (3)#@,转为字符。如果后面的字符为2-4,则返回最后一个字符,编译时会有“截断常量值”的警告。如果字符数大于4个,则编译时会有“常量中的字符太多”的错误。

         例子:

    #define CHAR(x)    #@x

         如:

         CHAR(1)等价于'1'(const char)。

         CHAR(abc)等价于'c'(const char)。

    一些常用的宏

    (1)do{...}while(0)  作用详见:http://kernelnewbies.org/FAQ/DoWhile0

         例子:

    #include <stdlib.h>
    #include <errno.h>
    
    #define ERR_EXIT(m) 
            do 
            { 
                    perror(m); 
                    exit(EXIT_FAILURE); 
            } while(0)

    (2)得到一个field在结构体(struct)中的偏移量

    #define OFFSETOF( type, field ) ( (size_t) &(( type *) 0)-> field )

         解释:

    • (type *)0:把0地址当成type类型的指针。
    • ((type *)0)->field:对应域的变量。
    • &((type *)0)->field:取该变量的地址,其实就等于该域相对于0地址的偏移量。
    • (size_t)&(((type *)0)->field):将该地址(偏移量)转化为size_t型数据。

         其实还有一种方式得到一个field在结构体(struct)中的偏移量:

    #define OFFSETOF(type, field) ( (size_t) ((char *)&((type *)0)->field - (char *)(type *)0) )

    (3)较为严谨的min(x, y)与max(x, y)的写法

    #define min(x, y) ({ 
                         typeof(x) _min1 = (x);  
                         typeof(y) _min2 = (y);  
                         (void) (&_min1 == &_min2); 
                         _min1 < _min2 ? _min1 : _min2; })
    
    #define max(x, y) ({ 
                         typeof(x) _max1 = (x);  
                         typeof(y) _max2 = (y);  
                         (void) (&_max1 == &_max2); 
                         _max1 > _max2 ? _max1 : _max2; })

         这么写的好处是:当不同类型的参数进行比较时,编译器会提示“warning: comparison of distinct pointer types lacks a cast.

    参考

    (完)

  • 相关阅读:
    七七四十九劫,九九八十一难
    Android中用layer-list编写阴影效果
    Android 高手进阶之自定义View,自定义属性(带进度的圆形进度条)
    Effective C++ 24,25
    windows系统port监听
    线程同步辅助类——Exchanger
    C/C++中constkeyword
    【COCOS2DX-游戏开发之三三】TMX边界控制与小窗体内预览TMX
    IDFA的值什么时候会发生改变
    hadoop(六)
  • 原文地址:https://www.cnblogs.com/helloamigo/p/3594936.html
Copyright © 2011-2022 走看看