宏的用法与简介

预处理指令

例如:#include<stdio.h>    #include<stdlib.h>    #define MAX 100......

因为它们是由预处理器解释的,所以称为预处理指令。预处理器读取代码,然后对其进行修改,并把修改过的代码传给编译器,再由编译器编译。在我们上述的例子当中预处理器用库函数stdio.h,stdlib.h的内容替换执行第一二条预处理指令,就像把库函数的内容写到了文件了一样。同理,对于标识符MAX也一样,在函数不变异阶段,编译器将所有的MAX都替换成20。

宏和标识符

标识符:#define NAME stuff

宏:#define NAME(参数列表) stuff

宏和标识符最主要的区别是宏有参数,而标识符没有参数,它们共同的特点都是在编译阶段,只要遇见NAME(NAME(参数列表)编译器就替换成stuff),通常将宏名大写,用以和函数区分。

宏的用法

#define定义了一个机制,宏允许把参数替换到文本当中,这种实现我们通常称为宏或者宏定义。我们需要注意宏的参数左 "(" 和宏名之间不能有空格。例如:#define NAME(5) X 是错误的,因为编译器会理解成标识符,而发生错误。还有一点就是宏的参数列表中的实际值会替换stuff中对应的值参数,为避免发生一些运算错误,需要我们在必要的地方加上括号以保证运算的正确性。

#define ADD(x)  x+x
int sum = ADD(2) * 10;
printf("%d\n",sum);

输出结果并不是我们想象中的40,而是22,这是因为在进行宏替换的时候会替换成  int sum = 2+2*10,所以为了避免宏在替换时因为优先级而引发错误,我们在 stuff 内能加括号的地方都加上括号, #define ADD(x)  ((x)+(x)),当参数太多时因为一行内放不下可以使用“\”续行符将参数写在多行。

“##”:这个符号可以把位于它两边的字符连成一个标识符。例如:

#define ADD_SUM(sum_num,value)
sum##sum_num = value

ADD_SUM(5,10)代表就是sum5 = 10,需要注意的是使用“##”连接生成的标识符必须是合法的。

#undef:这个指令用于移除一个宏定义,即一个现存的名字需要被重定义,则首先使用#undef将旧定义移除。

命令行定义:允许你在命令行中定义符号,用于启动编译过程。例如:char arr[ARR_SIZE],ARR_SIZE可以在命令行中定义,以便于在不同的条件下修改数组的大小。

条件编译:可以选择代码的一部分是被正常编译还是被忽略。

#if  connstant-expression(常量表达式,如果为真statement则参与编译,否则跳过编译)

      statement

#endif

如果我们要编译一段代码,可以如下图所示,当我们编译时将DEBUG设置为1,当我们要忽略时设置为0,这样就可以将代码保留在源文件中。

#define DEBUG 1
#if DEBUG
.......
#endif

条件编译还支持#elif,#else的格式,以便于选择不同的代码段编译:

#if        connstant-expression
               statement
#elif      connstant-expression
               statement
....................
#else      connstant-expression
               statement
#endif

可以嵌套使用。

是否被定义:测试一个符号是否被定义,如果定义,则可执行某个操作,比如调用一个函数。

#ifdef symbol
void fun( );
#endif

猜你喜欢

转载自blog.csdn.net/ypt523/article/details/80396999