转:C++中 #ifdef 和#endif的作用
一般情况下,源程序中所有的行都参加编译。但是有时希望对其中一部分内容只在满足一定条件才进行编译,也就是对一部分内容指定编译的条件,这就是“条件编译”。有时,希望当满足某条件时对一组语句进行编译,而当条件不满足时则编译另一组语句。
条件编译命令最常见的形式为:
#ifdef 标识符
程序段1
#else
程序段2
#endif
它的作用是:当标识符已经被定义过(一般是用#define命令定义),则对程序段1进行编译,否则编译程序段2。
其中#else部分也可以没有,即:
#ifdef
程序段1
#denif
在头文件中使用#ifdef和#ifndef是非常重要的,可以防止双重定义的错误。如你在头文件aaa.h中定义了一个类aaa如下:
class aaa
{
};
如果两次#include "aaa.h"(不见得是直接,也有可能两个不同的头文件中都包含了这个头文件)就会出错,因为相同的类不能定义两次。把aaa.h稍做修改:
#ifndef _aaa_
#define _aaa_
class aaa
{
};
#endif
就可以避免这样的问题。因为当你已经包含过这个文件,_aaa_就会有了定义,那么#ifndef的条件为假,就不会再执行后面的类定义了。
#ifdef和#endif必须成对使用。
从理论上讲可以出现在任何地方(头文件和实现文件中)
通常为了防止头文件被多次包含,在头文件中使用是必须的:
如:#ifndef MY_HEAD_H //头文件开头,名字是任意的,注意不要和其它头文件冲突
头文件声明
#endif //头文件结尾
有时候,在b.h中会include "a.h" ,在"c.h"中会include "b.h"及include"a.h", 这时,如果不用ifndef/endif,就会包含两次a.h,产生错误。
还是把头文件的内容都放在#ifndef和#endif中吧。不管你的头文件会不会被多个文件引用,你都要加上这个。一般格式是这样的:
#ifndef <标识>
#define <标识>
......
......
#endif
<标识>在理论上来说可以是自由命名的,但每个头文件的这个“标识”都应该是唯一的。标识的命名规则一般是头文件名全大写,前后加下划线,并把文件名中的“.”也变成下划线,如:stdio.h
#ifndef _STDIO_H_
#define _STDIO_H_
......
#endif
2.在#ifndef中定义变量出现的问题(一般不定义在#ifndef中)。
#ifndef AAA
#define AAA
...
int i;
...
#endif
里面有一个变量定义,在vc中链接时就出现了重复定义的错误,而在c中成功编译。
结论:
(1).当你第一个使用这个头的.cpp文件生成.obj的时候,int i 在里面定义了当另外一个使用这个的.cpp再次[单独]生成.obj的时候,int i 又被定义然后两个obj被另外一个.cpp也include 这个头的,连接在一起,就会出现重复定义.
(2).把源程序文件扩展名改成.c后,VC按照C语言的语法对源程序进行编译,而不是C++。在C语言中,若是遇到多个int i,则自动认为其中一个是定义,其他的是声明。
(3).C语言和C++语言连接结果不同,可能(猜测)时在进行编译的时候,C++语言将全局
变量默认为强符号,所以连接出错。C语言则依照是否初始化进行强弱的判断的。(参考)
解决方法:
(1).把源程序文件扩展名改成.c。
(2).推荐解决方案:
.h中只声明 extern int i;在.cpp中定义
<x.h>
#ifndef __X_H__
#define __X_H__
extern int i;
#endif //__X_H__
<x.c>
int i;
注意问题:
(1).变量一般不要定义在.h文件中。
下面是一个例子:编译后出现的错误---------fatal error C1189: #error : WINDOWS.H already in
种情况本质上就是对windows.h头文件重复引用,解决的办法,如果能不引用此头文件当然就不要引用,如果非得引用,或者是引用其他头文件导致的间接引用windows.h,那么不要在stdafx.h文件里面引用,一般可以解决。
或者可使用如下代码:
所以使用如下代码:
#ifdef _WINDOWS_
#undef _WINDOWS_
#endif
或者#ifndef #define #endif
如果还不行,就换一下头文件位置,#include "stdafx.h"放在#include <windows.h>之前
转于 http://www.cnblogs.com/renyuan/archive/2013/05/22/3092362.html
转:C++中 #ifdef 和#endif的作用的更多相关文章
- C++中 #ifdef 和#endif的作用
一般情况下,源程序中所有的行都参加编译.但是有时希望对其中一部分内容只在满足一定条件才进行编译,也就是对一部分内容指定编译的条件,这就是"条件编译".有时,希望当满足某条件时对一组 ...
- 【转载】C/C++中#ifdef和#endif的用法
转于 http://www.cnblogs.com/renyuan/archive/2013/05/22/3092362.html 今天笔试的时候遇到这个问题,整理一下! 一般情况下,源程序中所有的行 ...
- c/c++ 中#ifndef和#endif的作用及使用
有时候我们在编程的时候,希望有些代码在我们需要时编译,不需要时不编译,也就是让它快速注释,这时候即可以考虑#ifdef和#endif,它们会使我们的编译器进行选择性编译.使用方法如下: #includ ...
- 头文件中ifndef/define/endif的作用以及#pragma once使用
例如:要编写头文件test.h 在头文件开头写上两行: #ifndef _TEST_H #define _TEST_H//一般是文件名的大写 ············ ············ 头文件 ...
- #ifdef __cplusplus extern c #endif 的作用
#ifdef __cplusplus // C++编译环境中才会定义__cplusplus (plus就是"+"的意思) extern "C" { // 告诉编 ...
- C语言中#ifdef,#ifndef和#endif的作用
现在规定一下头文件书写规范, 根据陈皓编写的跟我一起些makefile,一定要记住:头文件中应该只是声明,而定义应该放在C/C++文件中.否则如果出现有定义,比如头文件中有int a =2;如果有多个 ...
- #ifdef _DEBUG/ #define new DEBUG_NEW/ #endif的作用
转载:https://blog.csdn.net/minghui_/article/details/80748142 转自:#ifdef _DEBUG #define new DEBUG_NEW #e ...
- ifndef/define/endif 的作用
转载自百度百科 ,感谢度娘 1 2 3 #ifdef语句1 //程序2 #endif 可翻译为:如果宏定义了语句1则执行程序2. 作用:我们可以用它区隔一些与特定头文件.程序库和其他文件版本有关的代码 ...
- C语言预处理命令之条件编译(#ifdef,#else,#endif,#if等)
转自:http://www.kuqin.com/language/20090806/66164.html 预处理过程扫描源代码,对其进行初步的转换,产生新的源代码提供给编译器.可见预处理过程先于编译器 ...
随机推荐
- cidaemon.exe进程cpu占用率高及关闭cidaemon.exe进程方法
问题描写叙述: 这段时间机器总是出现一个奇怪的问题:cidaemon.exe进程占用CUP率98%以上,大大影响了电脑的正常使用.资源管理器中出现多个cidaemon.exe进程,强制结束占用cp ...
- MVC ASPX(webForm)视图引擎 <%:%> 与<%=%>的差别
控制器 using System; using System.Collections.Generic; using System.Linq; using System.Web; using Syste ...
- gprof + kprof + gprof2dot (性能 与 函数调用图)-
http://www.cnblogs.com/rocketfan/archive/2009/11/15/1603465.html http://blog.csdn.net/stanjiang2010/ ...
- 3 - SQL Server 2008 之 使用SQL语句删除约束条件
基本语法为: ALTER TABLE 表名 DROP CONSTRAINT 约束名1,约束名2…… 如果删除一个约束,不需要逗号后的约束名,如果删除两个及两个以上的约束,必须以逗号隔开. 使用上一节中 ...
- Linux 用户与用户组
1 Linux 用户与组 Linux是一个多用户多任务操作系统.多用户可以在同一时间内登录同一个系统执行各自不同的任务,而互不影响. 1.1 Linux下用户的角色分类 Linux用户的角色分为3 ...
- 关于URL 解码, 编码
由于近期客户需要用到CA认证,此CA认证采用的是URL方式出传值 使用指定的编码对象将 URL 编码的字符串转换为已解码的字符串. 编码个人理解就是将某字符串以某种方式储存起来,而解码则以其编码格式得 ...
- css3购物网站商品文字提示实例
css3购物网站商品文字提示实例先来看效果图:<ignore_js_op> 当鼠标划过图片时,有着泰迪熊黑色长方形的背景就会出现.来看HTML5+CSS3代码: <!DOCTYPE ...
- VsSharp:一个VS扩展开发框架(上)
上篇:设计 一.引子 自2008年起开发SSMS插件SqlSharp(er)的过程中,有一天发现多数代码都大同小异,就像这样. Commands2 commands = (Commands2)_app ...
- Android手机修改Hosts的方法
Android手机是和Google帐号紧密联系的,由于中国的操蛋情况,很多时候Google帐号无法登录,导致Android市场无法使用. 在电脑上我们通过修改Hosts方法可以解决Google帐号的登 ...
- Sprite Kit教程:初学者
作者:Ray Wenderlich 原文出处:点击打开链接 http://www.raywenderlich.com/42699/spritekit-tutorial-for-beginners 转自 ...