美文网首页散文简友广场想法
C语言预处理器和宏、条件编译

C语言预处理器和宏、条件编译

作者: Cache_wood | 来源:发表于2020-12-24 00:11 被阅读0次

    @[toc]
    预处理器像是个小软件,可以在编译之前处理C语言程序。

    宏(macro)

    define指令定义了一个宏——用来代表其他东西的一个名字,包括常量和表达式。

    include指令告诉预处理器打开一个特定的文件,将它的内容作为正在编译的文件的一部分包含进来。


    预处理器会删除#define指令,会引入stdio.h指令,并且替换之后所有的#define定义的指令的内容。

    观察预处理器的输出

    大部分c的编译器提供了一种方法来观察预处理器的输出。

    #define N = 10
    #define INC(x) x+1
    #define SUB(x,y) x - y
    #define SQR(x) ((x)*(x))
    #define CUBE(x) (SQR(x)*(x))
    #define M1(x,y) x##y
    #define M2(x,y) #x #y
    
    int main(){
        int a[N],i,j,k,m;
    #ifdef N
        i = j;
    #else
        j = i;
    #endif
        i = 10 *INC(j);
        i = SUB(j,k);
        i = SQR(SQR(j));
        i = CUBE(j);
        i = M1(j,k);
        puts(M2(i,j));
    #undef SQR
        i = SQR(j);
    #define SQR
        i = SQR(j);
    
        return 0;
    }
    

    gcc编译器可以使用-E来查看预处理之后的输出。
    在cmd命令行环境下输入gcc -E macro_error.c -o macro,会产生macro文件,使用记事本打开之后就会看到预处理器的输出。

    预处理指令

    define 定义一个宏

    undef 删除一个宏定义

    include 导致一个指定文件的内容被包含到程序中

    条件编译 #if #ifdef #ifndef #elif #else #endif
    根据预处理器的条件确定是否包含

    带参数的宏

    #define N 10   //一般的宏
    #define MAX(x,y) ((x)>(y)?(x):(y))  //带参数的宏
    #define IS_EVEN(n) ((n)%2==0)
    

    括号不可缺少!!!

    宏的优点

    宏更“通用”
    程序可能稍微快一些

    宏的缺点

    编译之后的代码通常会变大
    宏参数没有类型检查
    无法用一个指针指向一个宏
    宏可能不止一次计算它的参数

    n = MAX(i++,j);
    n = (i++)>j?(i++):(j));
    

    #运算符

    :字符串化

    #define PRINT_INT(n) printf(#n " = %d\n",n)
    PRINT_INT(i/j);
    

    result:

    printf("i/j"" = %d\n",i/j);
    printf("i/j = %d\n",i/j);
    

    ##运算符

    :记号粘合

    #define MK_ID(n) i##n
    int MK_ID(1),MK_ID(2),MK_ID(3);
    

    result:

    int i1,i2,i3;
    

    宏的通用属性

    宏的替换列表可以包含对其他宏的调用。
    预处理器只会替换完整的记号,不会替换记号的片断。
    宏定义的作用范围通常到出现这个宏的文件末尾。
    宏不可以被定义两遍,除非定义完全相同。

    预定义宏、空的宏参数、参数个数可变的宏等内容我们就不过多介绍了。

    相关文章

      网友评论

        本文标题:C语言预处理器和宏、条件编译

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