#ifndef,#define,#pragma作用及用法

简介

#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

可能存在不足之处欢迎大家积极的发表自己的看法,指出,一起来讨论相关问题…我会不断更新修正后的内容的


  1. 来自博文(#pragma once用法总结) ↩︎

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值