简介
#ifndef是“if no define”的缩写,是宏定义的一种。它是预处理[!!!!!!!!!查看我的另一篇关于编译详解的博文(未发布)!!!!!!!!!!
]功能(宏定义,文件包含和条件编译)中的第三种——条件编译。
方式一:
#ifndef __HEADER_H__
#define __HEADER_H__
// 声明定义的语句
#endif
方式二:
#pragma once
// 声明定义的语句
这里__HEADER_H__
是宏,习惯上把这个宏定义成跟头文件名相似或一样。
这个宏主要是用于编译的时候避免重复include同一头文件而出现一些额重复定义/声明的问题。
而#pragma once
的功能上与上面的#ifndef...#define ....#endif
相同:都是使内容编译一次。
#ifndef
的方式依赖于宏名字不能冲突,这不光可以保证同一个文件不会被包含多次,也能保证内容完全相同的两个文件不会被不小心同时包含。当然,缺点就是如果不同头文件的宏名不小心“撞车”,可能就会导致头文件明明存在,编译器却硬说找不到声明的状况。1
#pragma once
则由编译器提供保证:同一个文件不会被包含多次。缺点是有的编译器不支持。
方式一:由语言支持所以移植性好,方式二:可以避免宏名字冲突
功能详解
C语言在对程序进行编译时,会先根据预处理命令进行“预处理”。(C语言编译系统包括预处理,编译和链接等部分 )预处理就会执行到编写的这些预处理命令。
#ifndef __HEADER_H__
#define __HEADER_H__
// 声明定义的语句
#endif
当执行到. #ifndef __HEADER_H__
时,编译器会在预处理阶段检查是否已经定义了__HEADER_H__
这个宏。如果没有定义的话就会执行下一个语句,也就是执行#define __HEADER_H__
这个指令,定义__HEADER_H__
这个宏,然后再执行后面的语句,进行语句的声明。如果定义了就会到#enfif
直接跳出中间区域。
也就是所谓的条件编译,防止了头文件的重复包含和编译。#ifndef
起到的效果是防止一个源文件两次包含同一个头文件,而不是防止两个源文件包含同一个头文件。
为什么这么说呢?举个简单的例子:
//主函数中
#include <stdio.h>
#include "functiona.h"
#include "functionb.h"
int main(){
int a=10,b=2,c=0;
c=functiona(a,b);
}
------------------------------------------
//functiona.c中
#include <stdio.h>
#include"functiona.h"
int functiona(int a,int b){
int result=0;
result=functionb(a,b)+666;
return result;
}
//在functiona.h中
int functiona(int a,int b);
int functionb(int a,int b);
-------------------------------------------
//functionb.c中
#include <stdio.h>
int functionb(int a,int b){
return a*b*PI;
}
//在functionb.h中
int functionb(int a,int b);
#define PI 3.14
上面是没有条件编译的,当编译时,就会发生错误。我们可以看出这是由于在主函数有#include "functiona.h" #include "functionb.h"
而在functiona.h
中又有int functiona(int a,int b);int functionb(int a,int b);
在预处理阶段:#include "functiona.h"
这个语句就会将functiona.h
这个文件内容替换到到这个语句位置。如果执行的话在主函数中就会多次定义PI
这样是不行的。
-----------------------------------------拥有条件编译后-----------------------------------
//主函数中
#include <stdio.h>
#include "functiona.h"
#include "functionb.h"
int main(){
int a=10,b=2,c=0;
c=functiona(a,b);
}
//functiona.c中
#include <stdio.h>
int functiona(int a,int b){
int result=0;
result=functionb(a,b)+666;
return result;
}
//在functiona.h中
#ifndef __FUNCTIONA_H__
#define __FUNCTIONA_H__
int functiona(int a,int b);
#endif
//functionb.c中
#include <stdio.h>
int functionb(int a,int b){
return a*b;
}
//在functionb.h中
#ifndef __FUNCTIONB_H__
#define __FUNCTIONB_H__
int functionb(int a,int b);
#define PI 3.14
#endif
可能存在不足之处欢迎大家积极的发表自己的看法,指出,一起来讨论相关问题…我会不断更新修正后的内容的