LinuxC程序设计基础—— 预处理命令

一丶结构体的定义

        宏定义(C语言标准允许在程序中用一个标识符来表示一个字符串,称为宏。标识符为宏名,在编译预处理时,将程序中的所有宏名用相应的字符串来替换,这个过程称为替换宏。宏分为两种: 无参数宏 和 有参数宏 )

        1.无参数宏(宏名后不带参数)

其通常定义的格式为:

                        #define    标识符    字符串

        其中的"#"表示这是一条预处理命令。凡是以"#"开头的均为预处理命令。"define"为宏定义命令。"标识符"为所定义的宏名。"字符串"可以是常数丶表达式丶格式串等。此外,长对程序中反复使用的表达式进行宏定义。

        例如:

                      #define    M    (y*y+3*y) 

        它的作用将这个M指定标识符来代替(y*y+3*y)这个表达式。在编写的所有程序源中,所有的 (y*y+3*y)这个表达式都用M代替,面对源程序编译时,将先由预处理进行宏替换,然后再编译。

        下图  例题示范:

            LinuxC程序设计基础—— 预处理命令

        定义无参数宏注意以下几点:

         ①    定义宏是用宏名来表示一个字符串,宏展开时以该字符串取代宏名。字符串可以是常数,也可是表达式,预处理不作任何检查。

          ②    宏定义不是说明或者语句,不用分号结束。

          ③    宏定义必须写在函数之外   作用从宏定义起到结束  如想结束作用域可使用#undef命令

          ④    宏名用括号扩起时,则预处理程序不对其宏代替。

          ⑤    宏定义允许嵌套,在宏定义的字符串可使用已经定义的宏名。在宏展开时由预处理程序层层代替

          ⑥    宏名习惯上用大写字母表示,以防止与变量混淆。但也可以使用小写字母。

          ⑦    可用宏定义表示数据类型,以便书写。

        2.有参数宏

其通常定义格式为:

                        #define    宏名    字符串

        如果由多个形参,像函数参数一样以逗号隔开

        带参宏调用的一般形式为:

                        宏名(实参表);

        例如:

                #define  M(y)  y*y+3*y                /*宏定义*/

                            ......

                k=M(5);                                        /*宏调用*/

                在宏调用时,用实参5去代替y,经处理宏展开后的语句为:k=5*5+3*5

        下图  例题示范:

                在编译前aaa(m+n)只是做了一个简单的替换成了m+n+n+n  结果变成了m+n+n+n *k;不要认为替换成了(m+n+n+n)*k;

            LinuxC程序设计基础—— 预处理命令

        设想如果将上题aaa(m+n)换成aaa(n+m)结果输出出来还是10吗?

        大部分人肯定会想和上题结果一样,但是结果却为8,因为宏替换只是单纯的字符替换,是不会做运算的,运算时编译以后的事情。

            LinuxC程序设计基础—— 预处理命令

        定义带参宏需注意以下几点:

        ①    宏名和形参表之间不能有空格

        ②    在函数中,形参和实参是两个不同的量,各有自己的作用域,调用时要把实参值赋予形参,进行“值传递”。而在带参宏中,只是符号代换,不存在值传递的问题。

        ③    宏定义中形参是标识符,宏调用中实参可是表达式。

        ④    字符串中的形参要用括号扩起。

二丶条件编译

        预处理程序提供了条件编译的功能。可以按不同的条件去编译不同的程序部分,产生不同的目标代码文件。程序源中所有的行都被编译,对一部分内容指定编译的条件,这就是条件编译。对于程序调试很有用。

        条件编译命令有以下几种模式:

        模式一:        #ifndef    标识符

                              程序段1

                              #else

                              程序段2

                              #dndif

        其含义是:如果没有定义标识符,就编译程序段1,否则编译程序段2.

        模式二:        #ifdef    标识符

                              程序段1

                              #else

                              程序段2

                              #endif

        其含义是:如果定义了标识符,就编译程序段1,否则编译程序段2.

        模式三:        #if    表达式

                              程序段1

                              #else

                              程序段2

                              #endif

        其含义是:如果表达式成立,就编译程序段1,否则编译程序段2.

三丶文件包含

        文件包含是C与处理程序中另一个重要功能。文件包含是指把指定源文件的全部内容包括到当前原程序文件中,从而把指定的文件和当前的源程序文件连成一个源文件。

        文件包含命令其形式为:

                        #include“文件名”    或者    #include<文件名>

        包含命令中的文件名可用双引号也可用尖括号,区别在于查找的指定文件位置不同。尖括号只在缺省目录里找指定文件,双引号则是现在源程序文件所在当前目录里查指定文件,若没有再去缺省目录里找。如果指定文件和当前编写的源程序出现在同一个目录里,就必须用双引号,否则编译程序回报告找不到指定文件。

        在前面我们已经多次用到命令包含过库函数的头文件,例如:

                        #include“stdio.h”       #include“math.h”

        程序设计中,文件包含是很有用的。一个大程序有多个模块儿多个程序员分别编写。有些公用的符号常量或宏定义课单独组成一个文件,在其他文件的开头用包含命令包含该文件即可使用。这样可以避免在每个文件都去书写那些公用量,从而节省时间,减少出错。

                                                                                                             LinuxC程序设计基础—— 预处理命令如有不足,请批评指正,谢谢