(源)http://blog.csdn.net/sky1203850702/article/details/42024673

首先,让我们先从头文件开始,在很多头文件里,我们会看到这样的语句

  #ifndef _MYHEADFILE_H
  #define _MYHEADFILE_H
  // .......语句......
  #endif // _MYHEADFILE_H
  为了避免同一个文件被include多次,我们常使用 #ifndef 进行判断,如果没有包含
  _MYHEADFILE_H , 则使用#define 来定义一个宏 _MYHEADFILE_H , #endif 与#ifndef
  首尾呼应,表示结束。
  说到这里,我们有必要提一个C语言中的预处理器,预处理器是一个小软件,它可以在编译前处理C程序,它的行为是由预处理指令控制的,预处理指令包含了以下内容:
  1,宏定义   #define
  2,文件包含 #include
  3,条件编译 #if
  #ifdef
  #ifndef
  #if defined
  #if !defined
  #elif
  #else
  #endif
  #undef
  指令都是以#开始的,我们来看一下简单的宏定义(对象式宏)
  #define  标准符  替换列表
  #define  PI  3.1415926
  可以对类型重命名
  #define  BOOL  int
  宏可以带参数,也是常说的宏函数
  #define 标识符(x1,x2...) 替换列表
  特别注意的是标识符和(之间不能有空格,圆括号是必须的。
  我们来看一下例子:
  #define MAX(x,y) ((x)>(y)?(x):(y))
  #define IS_EVEN(n) ((n)%2==0)
  #define TOUPPER(c) (‘a’<(c)&&(c)<’z’?(c)-’a’+’A’(c))
  #define SWAP(T,x,y) {T t=x; x=y; y=t}
  还可以写得更复杂一点,比如我们来写一个宏函数,用它来验证一个日期是否合法
  #define ISLEAP(y) ((y)%4==0&&(y)%100!=0||(y)%400==0)
  #define ISSMALL(m) ((m)==4||(m)==6||(m)==9||(m)==11)
  #define NORMAL(m) (ISSMALL(m)?30:31)
  #define DAYS(y,m) ((m)==2?28+ISLEAP(y):NORMAL(m))
  #define IN(x, from,to) ((x)>=(from)&&(x)<=(to))
  #define VALID(y,m,d) ((y)>1600&&IN(m,1,12)&&IN(d,1,DAYS(y,m)))
  下面我们来看看条件编译
  #if (comdition)
  {//语句##;}
  #endif
  如果(comdition)为真, 也就是逻辑1的话,编译下面的语句,如果(comdition)为假,即逻辑0,则不编译下面的语句。例子如下:
  #define DEBUG
  #if DEBUG
  Printf(“Value of i:%d\n”, i);
  Printf(“Value of j:%d\n”, j);
  #endif
  格式:
  #if  常量表达式
  常量表达式为0时,预处理器删除#if 和#endif中间的代码
  #if 会把没有定义过的标准符视做为0, 如果没有定义DEBUG, 则
  测试#if DEBUG 会失败,但#if !DEBUG会成功。
  可以用宏来定义文件名:
  #if define(IA32)
  #define CPU_FILE “ia32.h”
  #elif defined(IA64)
  #deifine CPU_FILE “ia64.h”
  #elif defined(AMD64)
  #define CPU_FILE “amd64.h”
  #endif
  #include CPU_FILE
  还可以取消已经定义的宏:
  #if defined VALUE              // 检验VALUE是否被定义 ,如果被定义
  #undef VALUE            // 解除语句定义
  #define VALUE 1000            //  重新定义VALUE 为1000
  #endif
  如果检验没有定义,可以这样写:
  #ifndef VALUE               // 如果VALUE没有被定义
  #define VALUE 1000          //  定义VALUE 为1000
  #endif
  以上所用的宏中:
  #undef为解除定义;
  #ifndef是if not defined的缩写,也可以写成#if !defined 即如果没有定义;
  #ifdef是if defined的缩写,也可以写成#if defined 即检查是否定义过;
  #ifdef 和 #if defined 的区别,#ifndef 与#if !defined 的区别相类似,都在于后者可以组成复杂的预编译条件,前者只判断单个宏是否定义,例如:
  #if defined(PERL_PACK_CAN_SHRIEKSIGN)
  /* v */ SIZE16,
  #else
  0,
  #endif
  #ifdef PERL_PACK_CAN_SHRIEKSIGN
  /* v */ SIZE16,
  #else
  0,
  #endif
  #ifdef是种简写,但不支持更复杂的表达式。
  #ifdef HAVE_MYHEADER
  # if VERSION > 3
  ...
  # endif
  #endif
  这种情况用
  #if defined(HAVE_MYHEADER) && VERSION > 3
  ...
  #endif
  更为合理

C++ #if #endif #define #ifdef #ifndef #if defined #if !defined详解 (转)的更多相关文章

  1. C/C++预处理指令#define,#ifdef,#ifndef,#endif… (转)

    本文转自博文C/C++预处理指令#define,#ifdef,#ifndef,#endif….这篇博文写得特别好,特转载. 本文主要记录了C/C++预处理指令,常见的预处理指令如下: #空指令,无任何 ...

  2. C/C++预处理指令#define,#ifdef,#ifndef,#endif…

    2016年12月29日更新: 今天查看以前文件的时候, 突然发现了#error 这个预处理指令.然后回想一下工作, 发现这个指令使用场景还是很多的.比如: 一个项目的模块儿之多,源文件之大,代码之多, ...

  3. C 和 Object-C中的 #ifdef #ifndef

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

  4. 条件编译#ifdef的妙用详解

    c语言中条件编译相关的预编译指令,包括  #define.#undef.#ifdef.#ifndef.#if.#elif.#else.#endif.defined. #define           ...

  5. C++中 #ifdef的妙用详解

    本文主要介绍c语言中条件编译相关的预编译指令,包括  #define.#undef.#ifdef.#ifndef.#if.#elif.#else.#endif.defined. #define     ...

  6. C/C++预处理指令#include,#define,#undef,#if,#ifdef,#ifndef,#elif,#endif,#error......

    本文主要记录了C/C++预处理指令,常见的预处理指令如下: #空指令,无任何效果 #include包含一个源代码文件 #define定义宏 #undef取消已定义的宏 #if如果给定条件为真,则编译下 ...

  7. ifndef/define/endif 和 #ifdef 、#if 作用和用法

    为了能简单的看看某些linux内核源码,复习了一下c语音,今天汇总了一下关于宏定义的相关内容: 一.ifndef/define/endif用法: .h文件,如下: #ifndef XX_H #defi ...

  8. uni-app条件编译:#ifdef #ifndef #endif

    语法: // #ifdef %PLATFORM% 这些代码只在该平台编译 // #endif #ifdef :      if defined  仅在某个平台编译 #ifndef :     if n ...

  9. #ifndef HeaderName_h #define HeaderName_h #endif 使用详解(转)

    原文:#ifndef HeaderName_h #define HeaderName_h #endif 使用详解 想必很多人都看到过头文件中写有:#ifndef HeaderName_h       ...

随机推荐

  1. 交作业啊,python爬取58的页面

    第一次写博文,好紧张啊,写这么烂怎么给别人看啊先做下总结: 刚开始学习python,自我感觉python写起来确实很方便,各种库,各种语法糖,不过刚接触,一下子记不下来这么多东西,总感觉乱乱的,用的多 ...

  2. 【从无到有】JavaScript新手教程——2.分支结构和循环

    介绍完JS的简介和向量以及运算符,大家对JS也有了初步的了解和认识,今天带大家来看一下JS中常用的分支结构以及循环结构是怎么使用的 [JS中的分支结构] 一.[if-else结构] 1.结构写法: i ...

  3. 在ASP dot Net Core MVC中用Controllers调用你的Asp dotnet Core Web API 实现CRUD到远程数据库中,构建你的分布式应用(附Git地址)

    本文所有的东西都是在dot Net Core 1.1环境+VS2017保证测试通过. 本文接着上次文章接着写的,不了解上篇文章的可能看着有点吃力.我尽量让大家都能看懂.这是上篇文章的连接http:// ...

  4. spring-mvc @Controller 200-不生效

    复杂的故事简单说,复杂的问题简单做.问题记录. 现象 新增加一个Controller,但在js中调用时报请求200,无请求反馈,重启服务多次,问题依旧. controller 分析 从问题现象分析:2 ...

  5. .net core CLI(创建VueJS||Angular结合的项目)

    net core cli 是快速创建模板项目 安装CLI 参考: https://www.hanselman.com/blog/dotnetNewAngularAndDotnetNewReact.as ...

  6. 计算机的启动和Linux的启动

    计算机的启动和Linux的启动 一 计算机的启动   计算机的启动过程分为四个阶段,分别是:BIOS.MBR.启动管理程序.加载操作系统内核.操作系统启动.   1.1 BIOS 计算机加电后,第一件 ...

  7. redis数据库入门

    Redis入门(1) 之安装.配置.安全登录 REmote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统. Redi ...

  8. 基于三层交换机和基于路由子接口的vlan间路由

    1:通过三层交换机实现vlan间的通信:为三层交换机创建vlan,设置交换机的两个SVI,并配置IP地址. (在二层交换机上只能配置一个SVI端口,用来实现交换机交换机远程管理,在三层交换机上可以配置 ...

  9. 【网站管理1】_dede织梦后台如何发布文章

    对于新手可能不了解,dede织梦后台是如何发文章的.下面说下我的经验. 发布文章步骤 1.打开浏览器,推介谷歌,360极速浏览器,火狐浏览器,输入网站后台网址   出现如下图登入界面 2.输入账号密码 ...

  10. poj2481 Cows 树状数组

    题目链接:http://poj.org/problem?id=2481 解题思路: 这道题对每组数据进行查询,是树状数组的应用.对于二维的树状数组, 首先想到排序.现在对输入的数据按右值从大到小排序, ...