[C++] 头文件中的#ifndef,#define,#endif以及#pragma用法
想必很多人都看过“头文件中用到的 #ifndef/#define/#endif 来防止该头文件被重复引用”。但是是否能理解“被重复引用”是什么意思?头文件被重复引用了,会产生什么后果?是不是所有的头文件中都要加入#ifndef/#define/#endif 这些代码?
1、 其实“被重复引用”是指一个头文件在同一个cpp文件中被include了多次,这种错误常常是由于include嵌套造成的。如:存在a.h文件#include "c.h"而此时b.cpp文件导入了#include "a.h" 和#include "c.h"此时就会造成c.h重复包含。
2、头文件被重复引用引起的后果:
(1)有些头文件重复引用,只是增加了编译工作的工作量,不会引起太大的问题,仅仅是编译效率低一些,但是对于大工程而言编译效率就是很重要的了。
(2)有些头文件重复包含,会引起编译错误,比如在头文件中定义了全局变量或写了函数的实现而不是声明(虽然这种方式不被推荐,但确实是C规范允许的),这种会引起重复定义。
3、 是不是所有的头文件中都要加入这些代码?
不是一定要加,但是不管怎样,用#ifndef/#define/#endif或者其他方式避免头文件重复包含,只有好处没有坏处。培养一个好的编程习惯是学习编程的一个重要分支。所以在写头文件时,最好是把内容都写在#ifndef和#endif之间。
4、以add.h为例
#ifndef _ADD_H_
#define _ADD_H_ //在这里包含add.h的类定义及变量和函数的声明
比如函数声明:int add(int a ,int b); //分号是必须加上的 #endif //_ADD_H_
编写add.cpp文件
#include"add.h"
int add(int a , int b)
{
return a+b;
}
主函数main.cpp文件
#include <iostream>
#include "add.h"
using namespace std; int main()
{
int a ;
a = add(,);
cout<<a<<endl;
return ;
}
1)程序中_ADD_H_为预处理器变量,书写格式一般是头文件名大写,前后加下划线,“.”用下划线代替。比如stdio.h表示为_STDIO_H_.
2)预处理器变量一般有两种状态:已定义或未定义。
#ifndef 指示检测指定的预处理器变量是否未定义,如果未定义,那么跟在后面的所有指示被处理,直到出现#endif;如果已定义,那么#ifndef测试为假,该指示和#endif指示间的代码都被忽略。
#define 指示接受一个名字并定义该名字为预处理器变量。
3)在调用该头文件时一般用#include "add.h"。
4)但是,必须记住的是预处理器仍将整个头文件读入,即使这个头文件所有内容将被忽略。由于这种处理将减慢编译速度,所以如果可能,应该避免出现多重包含。
5、#pragma的用法
#pragma once ... //此处放头文件中本来应该写的代码
#pragma once 是个预处理指令,在头文件的最开始加入这条指令表示:这个头文件只被编译一次,是由编译器提供保证:同一个文件不会被包含多次。注意这里所说的“同一个文件”是指物理上的一个文件,而不是指内容相同的两个文件。带来的好处是,你不必再费劲想个宏名了,当然也就不会出现宏名碰撞引发的奇怪问题。
6、总结:
#ifndef,#define,#endif是C/C++语言中的宏定义,通过宏定义避免文件多次编译。所以在所有支持C++语言的编译器上都是有效的,移植性好,所以如果写的程序要跨平台,最好使用这种方式。但缺点是宏名字不能冲突。
#pragma 可以避免名字冲突,缺点就是如果某个头文件有多份拷贝,本方法不能保证他们不被重复包含。且不是所有编译器都支持这种方式。
[C++] 头文件中的#ifndef,#define,#endif以及#pragma用法的更多相关文章
- 头文件中的#ifndef/#define/#endif 的作用
在一个大的软件工程里面,可能会有多个文件同时包含一个头文件,当这些文件编译链接成一个可执行文件时,就会出现大量重定义的错误.在头文件中实用#ifndef #define #endif能避免头文件的重定 ...
- 头文件里面的ifndef /define/endif的作用
c,c++里面,头文件里面的ifndef /define/endif的作用 今天和宿舍同学讨论一个小程序,发现有点地方不大懂······ 是关于头文件里面的一些地方: 例如:要编写头文件test.h ...
- 头文件种的ifndef/define/endif 是干什么用的
头文件种的ifndef/define/endif 是干什么用的? 答:防止头文件被重复包含.
- ifndef/define/endif作用和用法
问题:ifndef/define/endif”主要目的是防止头文件的重复包含和编译,偶只知道这个概念不懂的是怎么个用法,和为什么要用它~~高手请指点一下~~谢谢~~~!!! ------------- ...
- C++ ifndef /define/ endif 作用和用法
ifndef/define/endif”主要目的是防止头文件的重复包含和编译 比如你有两个C文件,这两个C文件都include了同一个头文件.而编译时,这两个C文件要一同编译成一个可运行文件,于是问题 ...
- ifndef /define/ endif 作用和用法
问题:ifndef/define/endif"主要目的是防止头文件的重复包含和编译====================================================== ...
- C++头文件为什么要加#ifndef #define #endif
#ifndef 在头文件中的作用 在一个大的软件工程里面,可能会有多个文件同时包含一个头文件,当这些文件编译链接成一个可执行文件时 ,就会出现大量“重定义”的错误.在头文件中实用#ifndef #de ...
- 头文件为什么要加#ifndef #define #endif
#ifndef 在头文件中的作用 在一个大的软件工程里面,可能会有多个文件同时包含一个头文件,当这些文件编译链接成一个可执行文件时 ,就会出现大量“重定义”的错误.在头文件中实用#ifndef #de ...
- #ifndef #define #endif 防止头文件被重复引用
想必很多人都看过“头文件中的 #ifndef/#define/#endif 防止该头文件被重复引用”.但是是否能理解“被重复引用”是什么意思?是不能在不同的两个文件中使用include来包含这个头文件 ...
随机推荐
- Spring Boot 默认指标从哪来?
了解有关 Spring Boot 默认指标及其来源的更多信息. 您是否注意到 Spring Boot 和 Micrometer 为您的应用生成的所有默认指标? 如果没有 - 您可以将 actuator ...
- 集群、限流、缓存 BAT 大厂无非也就是这么做
前言 前阵子有网友询问,如何优化网站?这个问题真的很大,跟他简单的聊了一下,随便说了几点,觉得有必要整理一篇文章出来,正好前阵子在做爬虫博客,于是把大体思路分享出来,与大家互通有无,共同进步. 优化 ...
- Android进阶之路(2)-详解MVP
### MVP简介 >MVP 全称:Model-View-Presenter :MVP 是从经典的模式MVC演变而来,它们的基本思想有相通的[地方](https://baike.baidu.co ...
- Leetcode Weekly Contest 152
退役老人现在连leetcode都不会做了 = = 今天早上做了leetcode第三题题目看错了,加上比赛中间还在调投稿的实验,一心二用直接gg 总结下教训就是 本渣现在做题连题目都看不清就开始做.开始 ...
- 用故事解析setTimeout和setInterval(内含js单线程和任务队列)
区别: setTimeout(fn,t): 延迟调用,超过了时间就调用回调函数,返回一个id,使用clearTimeout(id)取消执行. 注意:取消了里面的回调函数就不执行了哦,而不是取消的时候就 ...
- Calendar常用方法
import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; public class C ...
- 2019 Multi-University Training Contest 7
2019 Multi-University Training Contest 7 A. A + B = C 题意 给出 \(a,b,c\) 解方程 \(a10^x+b10^y=c10^z\). tri ...
- POJ-3259 Wormholes (ballman_ford 判负环)
ballman_ford 是对单源点到任意点最短路的处理方法(可以含负权边). 对所有边进行n-1次循环,(n为点得个数),如果此时源点到这条边终点的距离 大于 源点到这条边起点的距离加上路得权值就进 ...
- 大数乘法(适合k进制)
#include<stdio.h> #include<string.h> #define N 10000 void inv(char str[],int n) { int i, ...
- CF - 652 E Pursuit For Artifacts 边双联通
题目传送门 题解总结起来其实很简单. 把所有的边双联通分量缩成一个点,然后建立好新边, 然后再从起点搜到终点就好了. 代码: /* code by: zstu wxk time: 2019/02/23 ...