美文网首页
宏定义 预处理指令

宏定义 预处理指令

作者: 小李不木 | 来源:发表于2019-06-10 12:54 被阅读0次

     C语言提供的预处理指令主要有:宏定义、文件包含、条件编译

    1.C语言在对源程序进行编译之前,会先对一些特殊的预处理指令作解释(比如之前使用的#include文件包含指令),产生   一个新的源程序(这个过程称为编译预处理),之后再进行通常的编译

    2.为了区分预处理指令和一般的C语句,所有预处理指令都以符号"#"开头,并且结尾不用分号预处理指令在代码翻译成0和1之前执行。

    3.预处理指令可以出现在程序的任何位置,它的作用范围是从它出现的位置到文件尾。习惯上我们尽可能将预处理指令写在   源程序开头,这种情况下,它的作用范围就是整个源程序文件

    宏定义可以分为2种:不带参数的宏定义 和 带参数的宏定义。

    1:不带参数的宏:宏名一般用大写或者用K开头,变量名一般用小写。#define  宏名 字符串比如#define ABC 10右边的字符串也可以省略,比如#define ABC它的作用是在编译预处理时,将源程序中所有"宏名"替换成右边的"字符串",常用来定义常量。

    1> 宏名一般用大写字母,以便与变量名区别开来,但用小写也没有语法错误

    2> 对程序中用双引号扩起来的字符串内的字符,不进行宏的替换操作。

    3> 在编译预处理用字符串替换宏名时,不作语法检查,只是简单的字符串替换。只有在编译的时候才对已经展开宏名的源程序进行语法检查

    4> 宏名的有效范围是从定义位置到文件结束。如果需要终止宏定义的作用域,可以用#undef命令,使宏失效。

    5> 定义一个宏时可以引用已经定义的宏名

    2:带参数的宏例如: #define  sum(n1,n2) n1+n2

    可以实现函数的作用 :int sum (inta,int b)

    {return  a+b;}

    int  main ()

    {int c=sum(10,11);

    return0;}

    宏定义可以返回两个值的和。

    但是:int  c= sum (9,8)*(4,3);这个不能用宏替换,因为用宏的话会变成:int c= 9+8*4+3;

    这是因为带参数的宏在展开时,只作简单的字符和参数的替换,不进行任何计算操作。运算时在运行过程中进行的,而宏定义是在代码编译成0和1之前替换文本。所以在定义宏时,一般用一个小括号括住字符串的参数。

    注意:#define  pingfang (a)  (a*a)

    #define  pingfang (a)  a*a

    #define  pingfang (a)  ((a)*(a) )

    作用是不一样的。从整个使用过程可以发现,带参数的宏定义,在源程序中出现的形式与函数很像。但是两者是有本质区别的:宏定义不涉及存储空间的分配、参数类型匹配、参数传递、返回值问题函数调用在程序运行时执行,而宏替换只在编译预处理阶段进行。带参数的宏效率比函数高,因为函数调用时占用程序运行时间,在程序运行时才调用函数,要根据函数名找到相应的函数定义,而宏定义在程序编译之前就把代码换成相应的文本了。

    所以应该改成:  # define  sum(n1,n2)  ((n1)+(n2))

    条件编译:在很多情况下,我们希望程序的其中一部分代码只有在满足一定条件时才进行编译,否则不参与编译(只有参与编译的代码最终才能被执行),这就是条件编译。

    格式:  # if (条件1)code1

    #elif  (条件2)code2

    #elif  (条件3 )code3...

    #endif

    1> 如果条件1成立,那么编译器就会把#if 与 #elif之间的code1代码编译进去注意:是编译进去,不是执行,很平时用的if-else是不一样的)

    2> 如果条件1不成立、条件2成立,那么编译器就会把#elif 与 #else之间的code2代码编译进去

    3> 如果条件1、2都不成立,那么编译器就会把#else 与 #endif之间的code3编译进去4> 注意,条件编译结束后,要在最后面加一个#endif,不然当某个条件成立时,相应的code 会被编译,之后的多有语句不再有效,return 0 也不再有效。

    5> #if 和 #elif后面的条件一般是判断宏定义而不是判断变量,因为条件编译是在编译之前做的判断,宏定义也是编译之前定义的,而变量是在运行时才产生的、才有使用的意义条件编译与  if  else 很相像,但是两者也是有区别的:

    1:if ...else 是在程序运行过程中执行的,而 # if ...#endif 是在编译之前做的。

    2:# if ...#endif 不想执行的代码可以直接不参与编译,而if ...else中不管哪个条件成立,都会全部编译占据目标文件的空间。

    3:相比较下# if ...#endif 效率更高。

    例如:#define Max  10int main (){

    #if (Max==5)

    priintf("Max=%d\n",Max);

    #elif (Max==10)

    priintf("Max=%d\n",Max)

    ;#endifreturn 0; 

     }

    系统编译后程序相当于:

    #define Max  10int main (){

    priintf("Max=%d\n",Max);

    return 0;}

    #if 和 #elif后面的条件不仅仅可以用来判断宏的值,还可以判断是否定义过某个宏。

    #if defined(MAX)...code...#endif

    2: #ifdef的使用和#if defined()的用法基本一致#ifndef MAX...code...#endif

    如果前面没有定义过MAX这个宏,就将code编译进去

    相关文章

      网友评论

          本文标题:宏定义 预处理指令

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