c语言中宏定义#define

版权声明:均是学习笔记、心得,如有冒犯,请指出,会及时处理。https://blog.csdn.net/qq_27485531 https://blog.csdn.net/qq_27485531/article/details/82975055

预处理器指令#define和其他预处理器指令一样,都是从#开始运行,到第一个换行符结束为止,也就是说预处理器指令的长度仅限于一个逻辑行(C语言中以 ; 作为语句的结束,不以行为单位结束,当一行的内容太长不方便卸载一行时可使用反斜杠"\"作为继续符,分为多行书写) ,在预处理开始前编译器会把多行物理行处理为一行逻辑行。

#define LED_RGBOFF   LED_R_OFF;\                      /*反斜杠把该定义延续到下一行*/
                     LED_G_OFF;\
                     LED_B_OFF       

  等效于

#define LED_RGBOFF   LED_R_OFF;LED_G_OFF; LED_B_OFF  
                                      
                                            

 每行#define(逻辑行)都是由三部分构成                       

#define     PBGOFF        LED_R_OFF   
第一部分    第二部分        第三部分

 第一部分是预处理器指令本身#define

第二部分是用户自己定义的名字,也成为宏 ,有些宏代表值(如上例所示),这些宏被称为类对象宏,c语言还有类函数宏会在接下来介绍,宏的名称与变量的命名规则相同。只能使用字符数字和下划线,且首字符不能使数字。

第三部分称为替换列表或替换体 ,预处理找到宏后会用替换体代替宏。

例如:

#include <stdio.h>

#define  student_amount 10
#define  square_stu     student_amount*student_amount
#define  pa    printf("A is %d.\n",a)
#define  zxc   "A is %d.\n"

int main()
{                                  /*    等效于                           */
    int a = student_amount;        /*    int a = 10                      */
    pa;                            /*    printf("A is %d.\n",a)          */
    a = square_stu;                /*    a = 10*10                       */
    printf(zxc,a);                 /*    printf("A is %d.\n",a)          */
    
    return 0;
}

  运行上述程序后输出如下:

A is 10.
A is 100.

  在进行预编译时,预处理器不做计算,不对表达式求值,只进行替换。

  在前面提到过在一行的结尾加上反斜杠则可以使该行扩展至下一行如下所示

#define  kabuda "yuzhouwudi\
dashuaige"            /*反斜杠把该定义延续到下一行*/

    注意,第二行要与第一行对齐,如果这样做

#define  kabuda "yuzhouwudi\
                 dashuaige"            /*反斜杠把该定义延续到下一行*/

printf(kabuda);

    那么输出的内容是

 kabuda "yuzhouwudi            dashuaige"           

     从第二行开始到da之间的空格也算是字符串的一部分。

一般而言,预处理器发现程序的宏后,会用宏对应的替换体进行替换,如果替换的字符串中还包含宏,则继续替换这些宏。唯一例外的是双引号中的宏。

printf("kabuda");

  那么输出的结果是

kabuda

   另外在#define中使用参数可以创建外形和作用与函数类似的类函数宏 ,带有参数的宏看上去很像函数,因为这样的宏也使用圆括号。类函数宏定义的圆括号中可以有一个或多个参数,随后这些参数出现在替换体中。

#define  square_parameter(x)   x*x

   看上去和函数调用没有什么不同,其实还是有本质的区别,如下例所示,带有一些陷阱。

#include <stdio.h>

#define square_paramemter(a)   a*a

int main()
{
    int  x = 10;
    int  z;
    z = x;  
    printf("z = %d\n", z);
    z = square_paramemter(x);
    printf("z = %d\n", z);
    z = square_paramemter(x+2);
    printf("z = %d\n", z);

    return 0;
}

输出结果是

z = 10
z = 100
z = 22

第三个z为什么不是144,而是22,是因为我们前面提到的。预处理器不做计算,不求值,只替换字符序列,所以为10+2*10+2结果为22。

所以为了避免上例的错误,我们可以在宏定义的时候多加几个括号

#define   square_paramemter(a)   ((a)*(a))

猜你喜欢

转载自blog.csdn.net/qq_27485531/article/details/82975055