• GNU C 与 ANSI C(下)


    1. 语句表达式

    GNU C 把包含在括号中的复合语句看做是一个表达式,称作语句表达式,它可以出现在任何允许表达式的地方。我们可以在语句表达式中使用原本只能在复合语句中使用的循环、局部变量等,例如:

    #define min_t(type, x, y)   
    ({ type _x = (x); type _y = (y); _x < _y ? _x : _y; })
    
    int ia, ib, mini;
    float fa, fb, minf;
    
    mini = min_t(int, ia, ib);
    minf = min_t(float, fa, fb);
    

    因为重新定义了 _x 和 __y 这两个局部变量,所以以上述方式定义人宏将不会有副作用。在标准 C 中,对应的如下宏则会产生副作用:

    #define min(x, y) ((x) < (y) ? (x) : (y))
    

    代码 min(++ia, ++ib) 会被展开为 ((++ia) < (++ib) ? (++ia) : (++ib)),传入宏的“参数”被增加 2 次。

    2. typeof 关键字

    typeof(x) 语句可以获得 x 的类型,因此,我们可以借助 typeof 重新定义 min 这个宏:

    #define min(x, y)   ({          
        const typeof(x) _x = (x);   
        const typeof(y) _y = (y);   
        (void) (&_x == &_y);        
        _x < _y ? _x : _y;          })
    

    (void) (&_x == &_y) 的作用

    我们不需要像 min_t(type, x, y) 这个宏那样把 type 传入,因为通过 typeof(x)、typeof(y) 可以获得 type。代码行 (void)(&_x == &_y) 的作用是检查 _x 和 _y 的类型是否一致。

    3. 可变参数宏

    标准 C 就支持可变参数函数,意味着函数的参数是不固定,例如 printf() 函数的原型为:

    int printf(const char *format [, argument]...);
    

    而在 GNU C 中,宏也可以接受可变数目的参数,例如:

    #define per_debug(fmt, arg...)  
        printk(fmt, ##arg)
    

    这里 arg 表示其余的参数,可以是零个或多个,这些参数以及参数之间的逗号构成 arg 的值,在宏扩展时替换 arg,例如下列代码:

    pr_debug("%s : %d", filename, line)
    

    会被扩展为:

    printk("%s : %d", filename, line)
    

    使用“##”的原因是处理 arg 不代表任何参数的情况,这时候,前面的逗号就变得多余了。使用“##”之后,GNU C 预处理会丢弃前面的逗号。

    参考自:《Linux 设备驱动开发》

  • 相关阅读:
    shell中对于命令的搜寻顺序
    在shell中运行以不同方式运行脚本
    shell中的type命令
    shell中的数组
    shell中的循环语句
    shell中的case表达式
    双方括号
    34. Win7_x64安装oracle11g出现DIM-00019
    33. 完全卸载oracle11g步骤
    32. 安装oracle11g时,先决条件一直失败的解决方法
  • 原文地址:https://www.cnblogs.com/GyForever1004/p/8678541.html
Copyright © 2020-2023  润新知