C语言基础-预处理指令25

时间:2022-01-05 01:12:55

 1. 预处理指令的特点

 

    1). 都是以#开头.

    2).预处理指令都是在编译之前执行.

    3).预处理指令后面都没有分号.



2. 预处理指令的分类.

 

    1). 文件包含指令  #include

 

    2).宏定义: 可以将1C代码定义为1个标识,使用这个标识就可以使用这段代码.

 

    3).条件编译指令: 只编译指定的C代码为二进制指令.


3 预处理指令详解

   3.1 #include命令详解

         #include后可以包含任意类型,不仅.h可以,也可以.c,也可以.cpp。也就是其他的代码文件可以利用#include直接调用。

         #include内容不能重复包含,将会出现变量重名。即#include后所包含内容重复,不行。如aq.cpp包含date.h,若include.cpp调用了aq.cpp,就不需要再调用date.h了,否        则将出现变量重名,编译出错。变量的定义可以在头文件中,变量的运算可以在原文件中。也就是可以分开放。一般情况下,函数的声明,应该放在头文件。函数的实现        与变量的定义应当放在源文件。

      

    3.2  宏定义

          宏定义的作用:以为1C代码定义1个标识.如果你要使用这dC代码.那么你就使用这个标识就可以了.它是1个预处理指令.所以它在编译之前执行.

       语法:

              #define 宏名 宏值

              #define N 10

         宏的原理

               在预编译的时候,就会执行源文件中的预处理指令.

               会将C代码中使用宏名的地方替换为宏值.

               C代码中的宏名替换为宏值的过程叫做 宏替换/宏代换.


        带参数的宏

               在定义宏的时候,宏名是可以带参数的.在这个宏值当中.可以直接使用这个参数

            如果使用的宏有参数,那么就必须要在使用它的时候为这个宏的参数传值.

              1).先将传入的值传递给宏的参数,那么宏的参数的值就是我们传递的值.

              2).再把宏值当中使用参数的地方换成参数的值.

              3).最后,再将使用宏名的地方,替换为最后的宏值.

             使用带参数宏注意点

           1).宏不是函数,所以宏的参数不需要加类型说明符.直接写参数名就可以了.

           2).我们在定义宏的时候,编译器是如何区分宏名和宏值.

               #define 空格 宏名 空格.

               1个空格和第2个空格之间的内容会作为宏名

               2个空格以后的内容会作为宏值.

               所以.在写宏的时候,空格要小心了.

          3).为带参数的宏传值的时候,是本色传递.

               如果传递1个变量,并不是传递这个变的值

               而是直接传递的就是这个变量的串.


        在使用宏的时候需要注意的地方.

           1).宏名可以是任意的东东.宏值可以是任意的东西.在定义宏的时候,并不会去检查语法.

           2).无论宏值是什么东西,在定义宏的时候,不会去检查语法

                 只有当完成了宏替换的时候,才会去检查替换以后,是否符合语法规范.

           3).如果宏值是1个表达式,那么宏值并不是这个表达式的结果,而是这个表达式本身.

           4).如果宏值中包括1个变量名,那么在使用这个宏之前必须要保证这个变量已经存在.

           5).无法通过赋值符号为宏 改值. 因为宏根本就不是变量.

           6).宏的作用域.

              a. 宏可以定义在函数的内部 也可以定义在函数的外部.

              b. 从定义宏的地方,后面的所有的地方都可以直接使用这个宏.

                就算这个宏定义在这个大括弧里面,在这个后面 哪怕是大括弧外面都可以访问.

             c. 默认情况下,宏从定义的地方一直到文件结束都可以使用.

                #undef 宏名  可以让指定的宏提前失效.


          7).字符串中如果出现了宏名,系统不会认为这是1个宏,而认为是字符串的一部分.

             字符串中并不会出现宏替换.

          8).宏的层层替换.

             宏值当中我们用到了另外1个宏名.那么就会先将这个宏值当中的宏名替换为对应的宏值.

         9).如果后面跟了分号.那么就会吧分号作为宏值的一部分,替换的时候会连分号一起.虽然可以,但是不建议你加分号.

         10).宏值一旦换行,就任何宏定义结束了.所以你打算使用宏去替换函数的话,那么些的很恶心.

         #define    typedef的区别

        1).  #define1个预处理指令.在预编译的时候执行.在预编译的时候会吧宏名换成宏值.

              typedef1C代码.在运行的时候才会执行.

         2).  #define可以将任意的C代码取1个标识名.

              typedef只能为数据类型取名字.

     3.3条件编译指令

   

         3.3.1.条件编译指令.

 

             1).它是1个预处理指令.所以在预编译阶段执行.

             2).作用:

                  默认的情况下,我们所有的C代码都会被编译为二进制代码.

                 条件编译指令的作用:可以让编译器只编译指定部分的代码.


           3.3.2.条件编译指令的用法.


                #if 条件

                   C代码;

               #endif


              在预编译的时候,如果条件成立.就会将其中的C代码编译成二进制指令.

              如果条件不成立.就不会将其中的C代码编译成二进制指令.


              注意:条件只能是宏 不能是变量.

 

          #if 条件

                 C代码;

             #elif 条件

                C代码

            #elif 条件

                C代码

            #else

               C代码

           #endif


             条件编译指令和if语句的1个对比

 

            1).条件编译指令是1个预处理指令.在预处理阶段执行.

                 if语句是C代码.在程序运行的时候执行.

           2). if语句无论如何全部都要被编译为二进制指令.

                 条件编译指令:只会讲符合条件的C代码编译为二进制指令.

          3).实际上.if语句一定程度上可以换成条件编译指令.

                但是.条件编译指令的条件不能是变量参与.只能是宏.

 

 

           #ifdef 宏名

             C代码;

          #endif

          如果定义了指定的宏.就编译其中的代码否则就算了.

 

          #ifndef 宏名

          #endif

          如果没有定义指定的宏.就编译其中的代码否则就算了