一丶结构体的定义
宏定义(C语言标准允许在程序中用一个标识符来表示一个字符串,称为宏。标识符为宏名,在编译预处理时,将程序中的所有宏名用相应的字符串来替换,这个过程称为替换宏。宏分为两种: 无参数宏 和 有参数宏 )
1.无参数宏(宏名后不带参数)
其通常定义的格式为:
#define 标识符 字符串
其中的"#"表示这是一条预处理命令。凡是以"#"开头的均为预处理命令。"define"为宏定义命令。"标识符"为所定义的宏名。"字符串"可以是常数丶表达式丶格式串等。此外,长对程序中反复使用的表达式进行宏定义。
例如:
#define M (y*y+3*y)
它的作用将这个M指定标识符来代替(y*y+3*y)这个表达式。在编写的所有程序源中,所有的 (y*y+3*y)这个表达式都用M代替,面对源程序编译时,将先由预处理进行宏替换,然后再编译。
下图 例题示范:
定义无参数宏注意以下几点:
① 定义宏是用宏名来表示一个字符串,宏展开时以该字符串取代宏名。字符串可以是常数,也可是表达式,预处理不作任何检查。
② 宏定义不是说明或者语句,不用分号结束。
③ 宏定义必须写在函数之外 作用从宏定义起到结束 如想结束作用域可使用#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;
设想如果将上题aaa(m+n)换成aaa(n+m)结果输出出来还是10吗?
大部分人肯定会想和上题结果一样,但是结果却为8,因为宏替换只是单纯的字符替换,是不会做运算的,运算时编译以后的事情。
定义带参宏需注意以下几点:
① 宏名和形参表之间不能有空格
② 在函数中,形参和实参是两个不同的量,各有自己的作用域,调用时要把实参值赋予形参,进行“值传递”。而在带参宏中,只是符号代换,不存在值传递的问题。
③ 宏定义中形参是标识符,宏调用中实参可是表达式。
④ 字符串中的形参要用括号扩起。
二丶条件编译
预处理程序提供了条件编译的功能。可以按不同的条件去编译不同的程序部分,产生不同的目标代码文件。程序源中所有的行都被编译,对一部分内容指定编译的条件,这就是条件编译。对于程序调试很有用。
条件编译命令有以下几种模式:
模式一: #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”
程序设计中,文件包含是很有用的。一个大程序有多个模块儿多个程序员分别编写。有些公用的符号常量或宏定义课单独组成一个文件,在其他文件的开头用包含命令包含该文件即可使用。这样可以避免在每个文件都去书写那些公用量,从而节省时间,减少出错。
如有不足,请批评指正,谢谢