admin 发表于 2020-1-29 17:05:41

c99 宏备忘录

__LINE__    // 在源代码中插入当前源代码行号
__FILE__    // 在源文件中插入当前源文件名
__DATE__    // 在源文件中插入当前的编译日期
__TIME__    // 在源文件中插入当前编译时间
__STDC__    // 当要求程序严格遵循ANSI C标准时该标识被赋值为1
__cplusplus // 当编写C++程序时该标识符被定义
_WIN32      // 在程序运行在windows系统上被定义位1
linux       // 在程序运行在linux系统上被定义位1
__x86_64__// 在程序运行在64位系统上被定义位1
__i386__    // 在程序运行在32位系统上被定义位1
__VA_ARGS__ // 是一个可变参数的宏,这个可宏是新的C99规范中新增的,
            // 目前似乎gcc和VC6.0之后的都支持(VC6.0的编译器不支持)。
            // 宏前面加上##的作用在于,可以接受参数为0个或者多个
内置宏
#include <stdio.h>
int main()
{
    printf("__func__:%s\n", __func__);
    printf("__FILE__:%s\n", __FILE__);
    printf("__DATE__:%s\n", __DATE__);
    printf("__TIME__:%s\n", __TIME__);
    printf("__LINE__:%d\n", __LINE__);
    return 0;
}
#用来把参数转换成字符串
#define P(A) printf("%s:%d\n", #A, A);
int main()
{
    int a = 1, b = 2;
    P(a);
    P(b);
    P(a+b);
   
    return 0;
}
#define SQUARE(x) printf("The square of "#x" is %d.\n", ((x)*(x)))
int main()
{
    SQUARE(8);
   
    return 0;
}
##就是个粘合剂,将前后两部分粘合起来,也就是有“组成变量名”的意思。特别要和#运算符的功能区分开来,#是连接字符串,而##是连接变量名。
但是“##”不能随意粘合任意字符,必须是合法的C语言标示符。在单一的宏定义中,最多可以出现一次“#”或“##”预处理操作符。如果没有指定与“#”或“##”预处理操作符相关的计算次序,则会产生问题。为避免该问题,在单一的宏定义中只能使用其中一种操作符(即,一份“#”或一个“##”,或都不用)。除非非常有必要,否则尽量不要使用“#”和“##”。
#include <stdio.h>
#define XNAME(n) SYSTEM_ ## n
int main()
{
    int SYSTEM_ = 0,
      SYSTEM_OPEN = 1,
      SYSTEM_WRITE = 2,
      SYSTEM_CLOSE = 3;
   
    printf("%d\n", XNAME());
    printf("%d\n", XNAME(OPEN));
    printf("%d\n", XNAME(WRITE));
    printf("%d\n", XNAME(CLOSE));
    return 0;
}

此外,__VA_ARGS__ 是一个可变参数的宏,很少人知道这个宏,这个可变参数的宏是新的C99规范中新增的,目前似乎只有gcc支持(VC6.0的编译器不支持)。实现思想就是宏定义中参数列表的最后一个参数为省略号(也就是三个点)。
##__VA_ARGS__ 宏前面加上##的作用在于,当可变参数的个数为0时,这里的##起到把前面多余的逗号去掉的作用,否则会编译出错,相当于能够接受0个及以上的参数。
#include <stdio.h>
#define my_print1(fmt,...) printf(fmt, __VA_ARGS__)
#define my_print2(fmt,...) printf(fmt, ##__VA_ARGS__)
int main()
{
    int i = 0;
    int j=3;
    my_print1("iiijjj\n");// 错误打印
    //my_print1("i=%d,j=%d\n",i,j);// 正确打印
    //my_print2("iiijjj\n");      // 正确打印
    //my_print2("i=%d,j=%d\n",i,j); // 正确打印
}

#include <stdio.h>
#define my_print1(fmt,...) printf(fmt, __VA_ARGS__)
#define my_print2(fmt,...) printf(fmt, ##__VA_ARGS__)
int main()
{
    int i = 0;
    int j=3;
    //my_print1("iiijjj\n");// 错误打印
    my_print1("i=%d,j=%d\n",i,j);// 正确打印
    my_print2("iiijjj\n");      // 正确打印
    my_print2("i=%d,j=%d\n",i,j); // 正确打印
}




页: [1]
查看完整版本: c99 宏备忘录