C语言----预处理(高阶篇二十九)
宏定义
格式:
#define 标识符 字符串
如:
#define PI 3.1415926
以后程序一看见PI,就自动会用3.1415926替代。
注意:
※宏命令只是简单地替换字符串,但是它不做合法性检查。比如将3.1415926写成3.14T5926,只会在使用了PI的语句上报错,而不会在#define这行上报错。
※宏定义后面不得加分号
※宏定义后面的字符串可以省略。
如:
#define PI
※可以直接用宏定义一条语句。
如:
#define PT printf(“%d\n”,a)
以后就可以用PT来代替printf(“%d\n”,a)这条语句。
※在进行宏定义时,可以引用已定义的宏名,可以层层置换
#define R 3.0
#define PI 3.1415926
#define L 2*PI*R
#define S PI*R*R
main()
{
printf(“L=%f\nS=%f\n”,L,S);
}
运行情况如下:
L=18.849556
S=28.274333
※在字符串中的如果出现与宏名相同的字符串,不进行替换,如上面双引号中的L会原样输出。
※在学习宏命令时,一定要学会将它展开,再参与运算。如上面的printf函数层层展开,最后为:
printf(“L=%f\nS=%f\n”,2*3.1415926*3.0,3.1415926*3.0*3.0);
※宏定义和普通变量不同,它不分配内存空间
※宏名称虽然没有规定非用大写,但是在C程序员的书写习惯当中,经常使用大写,以区分它与普通变量和函数。
逻辑值
程序员可以自己用#define来定义TRUE和FALSE来增加程序的可读性。
※NULL在系统中已经被定义成#define NULL 0,EOF在系统中已经被定义成#define EOF -1
这样,在判断指针是否为空时,if(pi!=NULL)与if(pi)就没有什么分别。
那么,打开文件是否出错的代码可以缩减为:
if(!(fp=fopen(“file_a”,”r”))){……}
带参数的宏定义
宏定义也可以加上参数,这时它的功能有点类似函数,但是它和函数有本质上的区别。
格式:
#define 宏名(参数表) 字符串
如:
#define MUL(a,b) a*b
c=MUL(3,5);
展开得c=3*5;
※也可在参数表中代入复杂点的字符串。如:
c=MUL(2+3,1+2);
展开得:
c=2+3*1+2;
这行代码出现了问题:*号改变了两个参数的优先级,因此,一般带参宏替换的标准定义形式为:
#define c=MUL(a,b) (a)*(b)
上面的代码展开得:
c=(2+3)*(1+2);
这样展开的结果符合程序员意图。
※前面说过,还有一种方法可以使用“常量”,那就是用宏替换。
#define NUM 3
main()
{
int a[NUM];
}
用宏替换来定义数组,也是可以的。
什么叫“预处理”
每个程序在编译前,计算机会预先干一些事:那就是碰到预处理指令时,将它展开,得到真正的代码。如上面的代码经过编译器预处理后,得到的可运行代码实际上是:
main()
{
int a[3];
}
因此如果把#define NUM 3误写成#define NUM 3T,程序会在第3行报错。以此类推,如果在多个地方使用了NUM宏,编译器会在使用过NUM的行数上都报个错。
如果误写成#define NUM 3;(这里加了个分号)
在使用的时候 3的后面也会加分号。 比如: int a[NUM]; 就是 int a[3;]
文件包含
格式:
#include “文件名”
或
#include <文件名>
双引号一般用来包含用户文件名,尖括号一般用来包含系统自带的文件名。如stdio.h就是系统文件名,所以包含stdio.h时,就要用尖括号括起来。
有了文件包含功能以后,将一个大程序划分成多个文件就成为可能。多个文件可同时让多个人编写,再用#include将其它人写好的文件包含进来即可使用,不用关心它的细节。
程序1
用多文件模式计算任意两数之间所有整数之和
// 29-1用多文件模式计算任意两数之间所有整数之和.c // #include <stdio.h> #include "file1.h" //自定义头文件 main() { int a, b; printf("请输入两个整数:"); scanf_s("%d%d",&a,&b); fun(a, b); } //下面是 file1.h 里面的代码 //#pragma once // //void fun(int begin, int end) //{ // int s = 0; // for (int i = begin; i <= end; i++) // { // s += i; // } // printf("%d+%d+%d+...+%d+%d = %d\n", begin, begin + 1, begin + 2, end - 1, end, s); //}
※用#include包含的文件后缀一般是.h
※文件包含也可以嵌套
用多文件模式计算n的阶乘
// 29-2用多文件模式计算n的阶乘.c #include <stdio.h> #include "file2.h" main() { int a = 1; printf("请输入一个大于0的整数,求其阶乘\n"); scanf_s("%d", &a); printf("%d的阶乘是%d", a, fun(a)); } // file2.h 代码 //#pragma once // ////阶乘函数 //int fun(int a) //{ // int result = 1; // for (int i = 1; i <= a; i++) // { // result *= i; // } // return result; //}