`
NORRET
  • 浏览: 9351 次
  • 性别: Icon_minigender_1
  • 来自: 潍坊
社区版块
存档分类
最新评论

C++中#if #ifdef的作用

c++ 
阅读更多
一般情况下,源程序中所有的行都参加编译。但是有时希望对其中一部分内容只在满足一定条件才进行编译,也就是对一部分内容指定编译的条件,这就是“条件编译”。有时,希望当满足某条件时对一组语句进行编译,而当条件不满足时则编译另一组语句。
条件编译命令最常见的形式为:
/////////
#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,产生错误。
条件编译,满足条件就编译,否则就不编译,如果有一段代码有时候你想要,有时候又不想编译(比如为了调试),可以这样写: 
#if   1(0) 
          xxxxxx 
          xxxxxx 
#endif 
需要的时候写1,不要的时候改为0就可以了
文件中的#ifndef
头件的中的#ifndef,这是一个很关键的东西。比如你有两个C文件,这两个C文件都include了同一个头文件。而编译时,这两个C文件要一同编译成一个可运行文件,于是问题来了,大量的声明冲突。

还是把头文件的内容都放在#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中链接时就出现了i重复定义的错误,而在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;
分享到:
评论

相关推荐

    #ifdef,#else,#endif,#if用法详解

    #ifdef、#else、#endif、#if 是 C++ 预处理命令中最为常用的四个命令,它们都是用来实现条件编译的。下面我们将详细地介绍它们的用法和实例分析。 #ifdef 命令 #ifdef 命令是用来判断一个宏是否已经被定义,如果宏...

    #ifdef,#else,#endif和#ifndef的用法

    #ifdef、#else、#endif 和#ifndef 是 C/C++ 预处理命令中条件编译的四个基本指令,它们可以帮助开发者在编译前对代码进行选择性编译,从而实现代码的灵活使用和高效编译。 #ifdef 指令的用法 #ifdef 指令用来检测...

    预编译#define_#ifdef_#endif用法

    在C/C++编程中,预编译指令是代码编译过程中的重要组成部分,它们主要用于处理源代码中的条件编译和宏定义。`#define`, `#ifdef`, `#endif`等预编译指令帮助程序员根据特定条件来决定哪些代码应该被编译,从而实现...

    介绍c语言中条件编译相关的预编译指令

    #elif 命令若#if, #ifdef, #ifndef 或前面的#elif 条件不满足,则执行#elif 之后的语句,相当于 C 语法中的 else-if。 例如: ```c #if _DEBUG // ... #elif _RELEASE // ... #endif ``` 7. #else #else 命令与...

    C++预编译指令用法

    本文将详细介绍四个主要的预编译指令:`#undef`、`#ifdef`、`#ifndef` 和 `#if`,以及它们在实际编程中的应用。 首先,`#undef` 指令用于取消之前定义的宏定义。当你不再需要某个宏,或者想要改变其定义时,可以...

    c++条件编译详解

    C++中的条件编译主要通过预处理器指令实现。 #### 二、预处理器与条件编译 预处理器是编译过程的一个组成部分,其作用是对源代码进行初步的处理,然后再将处理后的代码传递给编译器进行进一步编译。预处理器的主要...

    C_C++中文函数手册.chm.zip

    6. **预处理器**:包括宏定义(#define)、条件编译(#if, #ifdef, #ifndef, #else, #endif)等,这些都是编译阶段进行代码修改的工具。 7. **输入/输出流**:C++中的iostream库提供了cin、cout、cerr等对象,用于...

    scpp-0.1

    在标签中提到的"#if"、"#ifdef"和"预处理"都是C/C++编程中的关键词。`#if`和`#ifdef`用来检查一个条件是否为真,如果条件满足,它们后面的代码块会被编译;如果不满足,则跳过。预处理是编译过程的一部分,它在...

    C/C++ 标准库函数 (中文版)

    预处理还包括条件编译命令#if、#ifdef、#ifndef、#else、#elif和#endif,这些命令允许编译器在满足特定条件时才编译代码的部分区域,这对于调试、生成不同版本的程序等场景非常有用。#error命令在遇到编译错误时可以...

    C C++语言中文参考文档

    预处理命令在编译器处理源代码之前执行,如#define用于常量定义,#include用于导入头文件,条件编译指令如#if、#ifdef等,这些内容对于理解和编写高效、可维护的代码至关重要。 接下来,文档详细阐述了C/C++的基本...

    Linux/C/C++函数中文使用手册

    C/C++的预处理阶段是编译过程的第一步,包括宏定义(#define)、条件编译(#if, #ifdef, #ifndef, #else, #endif)以及头文件包含(#include)。宏定义允许我们创建可替代的文本,而条件编译则根据特定的条件选择性...

    yingyong.rar_If...

    在C/C++、C#、Java等许多编程语言中,`#if`、`#ifdef`和`ifndef`是预处理器指令,它们在编译阶段起作用,而非运行时。这些指令在处理头文件、条件编译或针对不同平台进行编译时特别有用。让我们深入了解一下这三个...

    两个点H文件相互包含时的一种避免在编译的时候conflict的方法.docx

    在C语言中,条件编译是通过使用预处理命令来实现的,如#ifdef、#ifndef、#if等。 #ifdef命令的妙用 ifdef命令是条件编译中最常用的命令之一,它的作用是:当标识符已经被定义过时,编译程序段1,否则编译程序段2。...

    C++调用HTTP实现方式

    本文将详细介绍如何在C++中实现HTTP请求的发送与接收,包括GET和POST两种常见的方式。 #### 二、HTTP访问的基本概念 HTTP协议主要有两种请求方式:GET和POST。GET方式通常用于获取资源,而POST方式则用于向服务器...

    C++语言详解.pdf

    - **条件编译**: 使用#if、#ifdef、#ifndef等指令进行条件编译。 - **文件包含**: 使用#include指令包含其他头文件。 #### 2. 库函数 - **标准库**: 提供了一系列预先定义好的函数和类,如输入输出流(iostream)、...

    C/C++实训题目及答案

    1. **基础语法**:C和C++的基础语法是学习的起点,包括变量声明、数据类型(如int、char、float等)、运算符(算术、比较、逻辑等)、流程控制(如if语句、switch语句、for循环、while循环)。 2. **函数**:了解...

    IKM_c++的一些题目

    从给定的文件信息来看,这里涉及到的是IKM组织的C++编程评估考试中的部分问题。IKM是一家专业提供技能评估服务的公司,其C++评估考试旨在测试应试者在C++编程语言上的掌握程度。下面将针对提供的三个具体问题进行...

    托管C++ 文档+示例

    它通过在标准C++的基础上添加一系列新的语言特性和编译器支持,使得C++代码可以方便地调用.NET Framework中的类库,同时也允许.NET Framework中的代码调用C++编写的函数或类。 托管C++的主要特点包括: - **混合...

    c c++ 条件编译及其他

    条件编译是C和C++编程中的一种重要技术,它允许程序员根据特定的条件决定编译器应当处理哪些代码段。这种技术主要依赖于预处理指令,这些指令在实际编译之前由预处理器处理。 预处理器是C/C++编译过程的一部分,它...

Global site tag (gtag.js) - Google Analytics