预处理指令:在代码翻译成0和1之前执行的指令
主要有三种:宏定义、条件编译、文件包含。
都是以#开头,预处理指令的位置是随便写的,但有作用域:从编写指令的那一行开始到文件结束。
一、宏定义
宏定义可以分为带参数和不带参数两种。
1.不带参数
格式:#define 宏名 值
宏名一般都大写,也是为了避免让别人以为是变量,因为变量名都小写。也可以用小写k开头。
例如:
#define kCOUNT 6 这句代码意味着在编译前,会把代码中的所有kCOUNT都替换成6,双引号中的kCOUNT除外。
#undef kCOUNT 意味着宏失效,代表该句代码后面的kCOUNT无效了。
#include <stdio.h>
#define kCOUNT 50 //宏定义
int main()
{
int a=kCOUNT;//编译前就替换成了50
char *name="kCOUNT"; //不能替换
printf("a=%d\nname=%s\n",a,name);
#undef kCOUNT //宏定义失效
//int b=kCOUNT; 会报错
return 0;
}
2.带参数的宏定义
宏定义只负责文本替换,不负责运算!
#include <stdio.h>
#define sum(i,j) i+j //带参数的宏定义,将i+j用sum(i,j)表示
//正确写法:#define sum(i,j) (i+j)
#define plus(a) (a*a)
//正确写法:#define plus(a) ((a)*(a))
int main()
{
int a=sum(2,3);//a的值显然是2+3=5
printf("a=%d\n",a);
int b=sum(9,1)*sum(2,3);
/*
上述代码中我们的意愿显然是计算(9+1)*(2+3),但是,宏定义只是文本替换,不参与计算,
所以上述代码也就会被替换成9+1*2+3,这显然不是我们期待的。
所以,保险起见,我们应该在宏定义的值上加一个小括号-#define sum(i,j) (i+j)
*/
int c=plus(2+3);
/*
上述代码我们要表达的是(2+3)*(2+3),但由于宏定义不负责运算,所以结果就是
2+3*2+3,因此我们应该给每一个参数都加上小括号,即#define plus(a) ((a)*(a))
*/
return 0;
}
总结:
1>宏定义中带参数的表达式,每个参数和值都要加上小括号
2>宏定义比函数效率要高一些,因为宏定义是在编译前文本替换,而函数则是在运行时去调用函数。因此,一些小函数可以用宏定义。
二、条件编译
1.基本格式
#if() //括号可以省略
//执行语句。这里没有大括号也可以有两行以上的代码
#elif()
//执行语句
#else
//执行语句
#endif
注意:
1>条件语句不能访问代码中的变量,只能访问宏
2>哪个条件成立就编译哪个语句,其余的都不编译
3>若不加#endif,则后面的语句可能都不会参与编译,所以该语句必须有
#include <stdio.h>
#define kCOUNT 70
int main()
{
#if kCOUNT==70
printf("------\n");
printf("kCOUNT=%d\n",kCOUNT);
#elif kCOUNT==90
printf("========");
#else
printf("!!!!!!!!");
#endif
return 0;
}
/*
上述代码编译时其实就是这样的:
#include <stdio.h>
#define kCOUNT 70
int main()
{
printf("------\n");
printf("kCOUNT=%d\n",kCOUNT);
return 0;
}
*/
2.其他用法
/*
//假如定义了MAX这个宏定义
第一种:
#if defined (MAX)
.....
#endif
第二种
#ifdef MAX
...
#endif
//假如没定义MAX这个宏
第一种:
#if !defined (MAX)
.....
#endif
第二种
#ifndef MAX
...
#endif
*/
#include <stdio.h>
#define T 70
//#define A 34
int main()
{
#if defined (T)
printf("定义了T\n");
#endif
#if !defined (T)
printf("没有定义T\n");
#endif
#ifdef A
printf("定义了A\n");
#endif
#ifndef A
printf("没有定义A\n");
#endif
return 0;
}
三、文件包含
#include 拷贝文件到指定位置
注意:
1> <>表示系统自带的文件,“”代表自定义的文件
2>不能循环包含,比如a.h中包含了b.h,那么b.h中不能再包含a.h
3>重复包含会降低编译效率,为了避免重复,可以在.h文件中加条件编译
#ifndef ABC
#define ABC //值可以省略
int sum(int a,int b);//函数声明
#endif
/*
宏名必须唯一,避免跟其他.h中得相同,所以一般这个宏名定义成 文件名大写_H
*/