#ifdef #if defined( ) #if (condition)的用法

原创
2016/06/14 19:28
阅读数 2.3K

一、引言

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

  #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 1   //后面必须有相应的值,否则会报错;要么就干脆不要定义,会被当作0,即条件不成立。

  #if DEBUG         //也可以写成 #if DEBUG>0

  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 defined(IA32)    //没有#if define这种写法

  #define CPU_FILE “ia32.h”

  #elif defined(IA64)

  #define 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

  更为合理

所谓的复合用法,注意defined里面判断的还是某个宏是否有定义,但是它可以与其他条件组合,而对于#ifdef语句就不存在这种用法。

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部