zoukankan      html  css  js  c++  java
  • C++ #if #endif #define #ifdef #ifndef #if defined #if !defined详解 (转)

    (源)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 ”, i);
      Printf(“Value of j:%d ”, 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
      更为合理
  • 相关阅读:
    集合类源码(六)Map(HashMap, Hashtable, LinkedHashMap, WeakHashMap)
    CycleBarrier与CountDownLatch原理
    Volatile和Synchronized
    集合类源码(五)Collection之BlockingQueue(LinkedTransferQueue, PriorityBlockingQueue, SynchronousQueue)
    集合类源码(三)Collection之List(CopyOnWriteArrayList, Stack)
    集合类源码(二)Collection之List(ArrayList, LinkedList, Vector)
    集合类源码(一)概述
    Java ReentrantLock中tryLock与lock的区别(非公平锁与公平锁)
    Arctime制作视频字幕教程
    用Pr对视频画面进行裁剪
  • 原文地址:https://www.cnblogs.com/Call-C/p/6951769.html
Copyright © 2011-2022 走看看