作用:防止头文件的重复包含和编译

定义

  #ifndef x

  #define x

  ...

  #endif

  这是宏定义的一种,它可以根据是否已经定义了一个变量来进行分支选择,一般用于调试等等.实际上确切的说这应该是预处理功能中三种(宏定义,文件包含和条件编译)中的一种----条件编译。 C语言在对程序进行编译时,会先根据预处理命令进行“预处理”。C语言编译系统包括预处理,编译和链接等部分。

  #ifndef x

  //先测试x是否被宏定义过

  #define x

  //如果没有宏定义下面就宏定义x并编译下面的语句

  ...

  #endif

  //如果已经定义了则编译#endif后面的语句

  条件指示符#ifndef检查预编译常量在前面是否已经被宏定义。如果在前面没有被宏定义,则条件指示符的值为真,于是从#ifndef到#endif之间的所有语句都被包含进来进行编译处理。相反,如果#ifndef指示符的值为假,则它与#endif指示符之间的行将被忽略。条件指示符#ifndef 的最主要目的是防止头文件的重复包含和编译。

补充一些内容

  千万不要忽略了头件的中的#ifndef,这是一个很关键的东西。比如你有两个C文件,这两个C文件都include了同一个头文件。而编译时,这两个C文件要一同编译成一个可运行文件,于是问题来了,大量的声明冲突。

  还是把头文件的内容都放在#ifndef和#endif中吧。不管你的头文件会不会被多个文件引用,你都要加上这个。一般格式是这样的:

  #ifndef <标识>

  #define <标识>

  ......

  #endif

  <标识>在理论上来说可以是自由命名的,但每个头文件的这个“标识”都应该是唯一的。标识的命名规则一般是头文件名全大写,前后加下划线,并把文件名中的“.”也变成下划线,如:stdio.h

  #ifndef _STDIO_H_

  #define _STDIO_H_

  ......

#endif

#ifndef xxx//如果没有定义xxx
#define xxx//定义xxx
#endif //结束如果
这个用法主要是在头文件中,主要是为了防止类重复的include,所以在类的头文件之前加上前面两个,用类名替代xxx,在最后加上最后一句。
const 与 #define的比较
    C++ 语言可以用const来定义常量,也可以用 #define来定义常量。但是前者比后者有更多的优点:
(1)       const常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查。而对后者只进行字符替换,没有类型安全检查,并且在字符替换可能会产生意料不到的错误(边际效应)。
 
(2)       有些集成化的调试工具可以对const常量进行调试,但是不能对宏常量进行调试。
        【规则5-2-1】在C++ 程序中只使用const常量而不使用宏常量,即const常量完全取代宏常量。

拓展阅读百度百科

#ifndef的用法的更多相关文章

  1. #ifdef #else #endif #if #ifndef 的用法

    预编译就是在对源文件进行处理之前(如在语法扫描和分析之前),先处理预处理部分,精简代码,然后再进行编译. 预处理命令有:#include 文件包含.#define 宏定义.以及要重点讲的#if.#if ...

  2. (转)#ifndef的用法

    原文链接:http://wenku.baidu.com/link?url=c4doqVo3U429RkwTN5eaJIfD2rEu-1bLKKQXuqO8drmL359PhUjVmzC7P94wBY9 ...

  3. #ifndef 的用法

    背景: 头件的中的#ifndef,这是一个很关键的东西.比如你有两个C文件,这两个C文件都include了同一个头文件.而编译时,这两个C文件要一同编译成一个可运行文件,会引起大量的声明冲突,这时候需 ...

  4. #ifndef 的用法介绍

    ifndef是 if not define 的缩写,一种宏定义.它是预处理功能中三种(宏定义,文件包含和条件编译)中的第三种--条件编译. 其使用方式是: #define X ... #endif / ...

  5. #ifdef #else #endif #fi #ifndef 的用法

    预处理就是在进行编译的第一遍词法扫描和语法分析之前所作的工作.说白了,就是对源文件进行编译前,先对预处理部分进行处理,然后对处理后的代码进行编译.这样做的好处是,经过处理后的代码,将会变的很精短.   ...

  6. C++ pragma once 与 ifndef 用法区别

    #pragma once 与 #ifndef 的作用 (1)在C/C++中,在使用预编译指令#include的时候,为了防止重复引用造成二义性. (2)在能够支持这两种方式的编译器上,二者并没有太大的 ...

  7. C 和 Object- C 中得 #ifdef 和#ifndef

    很多宏是为了进行条件编译.一般情况下,源程序中所有的行都参加编译.但是有时希望对其中一部分内容只在满足一定条件才进行编译,也就是对一部分内容指定编译的条件,这就是“条件编译”.有时,希望当满足某条件时 ...

  8. 对#ifndef的理解

    由于对#ifndef的用法不太理解,在询问了老师#ifndef的含义以及查找资料后,对#ifndef总结了以下几点: <1> #ifndef是宏定义的一种,是三种预处理功能(宏定义,文件包 ...

  9. 关于#ifdef #ifndef

    https://www.cnblogs.com/agnily/p/5848768.html 1.先看#ifdef的用法: #define KEY1_PA0 #ifdef KEY1_PA0 ------ ...

随机推荐

  1. PHP 中的新语法 new static 是个啥意思?

    简单通俗的来说, self就是写在哪个类里面, 实际调用的就是这个类.所谓的后期静态绑定, static代表使用的这个类, 就是你在父类里写的static, 然后通过子类直接/间接用到了这个stati ...

  2. codeforces 691E 矩阵快速幂+dp

    传送门:https://codeforces.com/contest/691/problem/E 题意:给定长度为n的序列,从序列中选择k个数(可以重复选择),使得得到的排列满足xi与xi+1异或的二 ...

  3. gdb打印STL和boost容器

    http://note.youdao.com/noteshare?id=b581e0db0084b6ba3011d9d27d372c91

  4. 【题解】Berland.Taxi Codeforces 883L 模拟 线段树 堆

    Prelude 题目传送门:ヾ(•ω•`)o Solution 按照题意模拟即可. 维护一个优先队列,里面装的是正在运营中的出租车,关键字是乘客的下车时间. 维护一个线段树,第\(i\)个位置表示第\ ...

  5. 斯皮尔曼等级相关(Spearman’s correlation coefficient for ranked data)

    sklearn实战-乳腺癌细胞数据挖掘(博主亲自录制视频) https://study.163.com/course/introduction.htm?courseId=1005269003& ...

  6. CSS3笔记-加强版

    属性选择器:   E[attr]只使用属性名,但没有确定任何属性值 E[attr="value"]指定属性名,并指定了该属性的属性值 E[attr~="value&quo ...

  7. Atcoder #014 agc014_C BFS

    LINK 题意:给定起点和最大操作次数$k$,地图'#'为上锁房间, 每次可以走$k$步,并任意解锁$k$个房间,问到达地图边界的最小次数. 思路:其实上锁与否并没有关系,因为先把$k$步走的次数用完 ...

  8. C语言中的序列点

    TAG: C, 序列点 DATE: 2013-08-07 序列点是程序执行序列中一些特殊的点. 当有序列点存在时,序列点前面的表达式必须求值完毕,并且副作用也已经发生, 才会计算序列点后面的表达式和其 ...

  9. 51nod 1074 约瑟夫环 V2

    N个人坐成一个圆环(编号为1 - N),从第1个人开始报数,数到K的人出列,后面的人重新从1开始报数.问最后剩下的人的编号. 例如:N = 3,K = 2.2号先出列,然后是1号,最后剩下的是3号. ...

  10. 【BZOJ】2142 礼物

    [算法]中国剩余定理 [题意]给定n件物品分给m个人,每人分到wi件,求方案数%p.p不一定是素数. [题解] 首先考虑n全排列然后按wi划分成m份,然后对于每份内都是全排列,除以wi!消除标号影响, ...