C语言的预处理指令
一.核心用法:
1.所有的预处理指令都是以#开头
2.预处理指令在代码翻译成0和1之前执行
3.预处理的位置是随便写的
4.预处理指令的作用域:从编写指令的那一行开始,一直到文件结尾,可以用#undef取消宏定义的作用
5.宏名一般用大写或者以k开头,变量名一般用小写
二.宏定义
// *宏定义是让下面的代码在编译之前就将#define A B 后面的A换成B
#define 和#undef 是成对出现的 从#define开始 从直到#undef结束
int main()
{
char *name = "COUNT";
printf("%s\n", name);
#define COUNT 4
int ages[COUNT] = {1, 2, 67, 89};
for ( int i = 0; i<COUNT; i++) {
printf("%d\n", ages[i]);
}
#undef COUNT
// *带参数的宏定义效率比函数高
#define sum(v1, v2) ((v1)+(v2))
int main()
{
int a = 10;
int b = 20;
int c = sum(a, b);
printf("c is %d\n", c);
return 0;
}
注意点:
所有的预处理指令都是纯替换不包含任何优先级 所以要把里面的每一个参数都加上括号。比如下面这道题目测应该是100.
例:
#define pingfang(a) ((a)*(a))
int main()
{
// 如果没括号就是 5+5*5+5 因为*优先级>+ 所以答案是35
int c = pingfang(5+5);
printf("c is %d\n", c);
return 0;
}
三.条件编译
条件编译相比与if结构,效率更高性能更好,在某些大型的程序里if的每一个分支的代码量都很多,如果用了条件编译,不需要用到的代码直接就不用编译了。
#if和#endif是成对出现的 只要写了#if,在最后面必须加上#endif
#ifndef 相当于 ifdefine的否定语态
例:
#define A 5
int main()
{
#ifndef A
printf("哈哈\n");
#endif
/*
int a = 10;
if (a == 10)
{
printf("a是10\n");
}
else if (a == 5)
{
printf("a是5\n");
}
else
{
printf("a其他值\n");
}
*/
#if (A == 10)
printf("a是10\n");
#elif (A == 5)
printf("a是5\n");
#else
printf("a其他值\n");
#endif
return 0;
}
四.文件包含
1.<>表示系统自带的文件,""表示自定义的文件
2.不允许循环包含,比如a.h包含b.h,b.h又包含a.h
使用文件包含预处理指令的好处:
某些类的.h文件中包含了很多方法,结果程序员在用到一个方法时想到要导入一下这个.h再用到一个又导入了一次,每次#include 相当于把目标.h文件全部复制到本代码里,造成许多代码重复从而影响编译速度和执行效率,所以在.H文件之前加上两条预处理指令:
#ifndef WANGWU_H
#define WANGWU_H
意思是如果没有导入 那就导入,后面的命名规范是文件名+下划线h 全是大写
#include "lisi.h"
#include "wangwu.h"
#include <stdio.h>
int main()
{
int c = sum(10, 19);
printf("c is %d\n", c);
return 0;
}
#ifndef LISI_H
#define LISI_H
int sum(int a, int b);
#endif
#ifndef WANGWU_H
#define WANGWU_H
int minus(int a, int b);
#endif
用了文件头预处理指令之后就不用担心.h文件导入多少次了,都只会编译一次。