条件编译及头文件包含
1.条件编译
在编译一个程序的时候我们如果要将一条语句(一组语句)编译或者放弃是很方便的。因为我们有条件编译指令。
比如说:
调试性的代码,删除可惜,保留又碍事,所以我们可以选择性的编译
常见的条件编译指令:
(1)
#include <stdio.h>
#include <stdlib.h>
#define max 1
int main(void)
{//#if只能放常量表达式,变量在程序运行创建,编译是预处理,不会真的创建变量//如果max为真,就编译语句,否则就放弃
#if (max){printf("hello world \n");}
#endifreturn 0;
}
(2)多分枝的条件编译
#include <stdio.h>
#define max 1
int main(void)
{//#if只能放常量表达式,变量在程序运行创建,编译是预处理,不会真的创建变量//如果语句成立,就执行编译,否则就放弃编译
#if (max==3){printf("hello world \n");}
#elif(max==4)printf("你好\n");
#elif(max==6)printf("假期快乐\n");
#elseprintf("开学快乐\n");
#endifreturn 0;
}
这个地方的elif相当于else if,但是在条件编译中无法使用else if只能使用elif
(3)判断是否被定义
#include <stdio.h>
#define max 1
int main(void)
{
#ifdef max//如果定义过max,编译括号语句,否则就放弃{printf("hello world \n");}
#endifreturn 0;
}
或者这样写也可以
#include <stdio.h>
#define max 1
int main(void)
{
#if defined(max)//如果定义过max,编译行括号语句,否则就放弃{printf("hello world \n");}
#endifreturn 0;
}
(4)判断是否未被定义
#include <stdio.h>
#define max 1
int main(void)
{
#if !defined(max)//如果没定义过max,编译括号语句,否则就放弃{printf("hello world \n");}
#endifreturn 0;
}
也可以这样写
#include <stdio.h>
#define max 1
int main(void)
{
#ifndef max//如果没定义过max,编译括号语句,否则就放弃{printf("hello world \n");}
#endifreturn 0;
}
(5)也可以嵌套使用
#include <stdio.h>
#define max 1
int main(void)
{
#ifndef max{
#ifdef miniprintf("hehe");
#elifprintf("haha");
#endifreturn 1;}
#elif defined (max){
#if defined(mini)printf("哈哈");
#endifprintf("呵呵");}
#endifreturn 0;
}
2.头文件被包含的方式
(1)本地文件被包含的方式
#include "example.h"
查找策略:先在源文件所在目录下查找,如果该头文件未找到,编译器就像查找库函数头文件一样在标准位置查找头文件。
如果找不到就提示编译错误。
(2)库文件被包含的方式
#include <stdio.h>
查找策略:查找头文件直接去标准路径下去查找,如果找不到就提示编译错误。
这样是不是可以说,对于库文件也可以使用“”的形式包含?
答案是肯定的,可以,
但是这样做查找的效率就低些,当然这样也不容易区分是库文件还是本地文件
3.嵌套文件包含
#include指令可以使另外一个文件被编译。
就像它实际出现于#include 指令的
这种替换的方式很简单:预处理器先删除这条指令,并用包含文件的内容替换。
一个头文件被包含10次,那就实际被编译10次,如果重复包含,对编译的压力就比较大。
这样预处理后代码量会剧增。如果工程比较大,有公共使用的头文件,被大家都能使用,又不做任何的处理,那么后果真的不堪设想。
如何解决头文件被重复引入的问题?
方法1:条件编译。
每个头文件的开头写:
#ifndefine 文件名#define 文件名#endif
方法2:
#pragma once
就可以避免头文件的重复引入