转自:https://blog.csdn.net/zhangchiytu/article/details/7563329

先看个例子:
#define TARGET_LITTLE_ENDINA 1
#define TARGET_BIG_ENDINA   0

#ifdef TARGET_LITTLE_ENDINA
call little endina function
#else
call big endina function
#endif
不管把 TARGET_LITTLE_ENDINA 和 TARGET_BIG_ENDINA定义成0或者1,甚至后面不写这个0或者1 ,调用的都是little endina函数,这段代码是有问题的,就是没有理解#if和#ifdef之间的区别。

#if 的使用说明
#if的后面接的是表达式,如果表达式为1,则编译#if下面的代码

 #if (MAX==10)||(MAX==20)
...code...
#endif

它的作用是:如果(MAX==10)||(MAX==20)成立,那么编译器就会把其中的#if 与 #endif之间的代码编译进去(注意:是编译进去,不是执行!!)

#ifdef 的说明
#ifdef 后面接的是一个宏

 #ifdef (x)
...code...
#endif

这个#ifdef 它不管里面的“x”的逻辑是“真”还是“假”,它只管这个程序前面的宏定义里面有没有定义“x”这个宏(即在这里#define  x 1和#define  x 0等效,都等同于#define x)。

如果定义了x这个宏,那么编译器会编译中间的…code…否则直接忽视中间的…code…代码。

#if defined的使用
#if defined() 的使用和#ifdef的用法一致
#if !defined()又和 #ifndef 的用法一致。

最后强调两点:
第一:这几个宏定义只是决定代码块是否被编译!
第二:别忘了#endif

#ifdef 的用法
灵活使用#ifdef指示符,我们可以区隔一些与特定头文件、程序库和其他文件版本有关的代码。define.cpp文件:

 #include "iostream.h"
int main()
{
  #ifdef DEBUG
cout<< "Beginning execution of main()";
  #endif
return ;
}

运行结果:Press any key to continue

改写代码如下:

 #include "iostream.h"
#define DEBUG
int main()
{
#ifdef DEBUG
cout<< "Beginning execution of main()";
#endif
return ;
}

运行结果为:Beginning execution of main()
Press any key to continue

更一般的情况是,#define语句是包含在一个特定的头文件中。
比如,新建头文件head.h,在文件中加入代码:

 #ifndef DEBUG
#define DEBUG
#endif

而在define.cpp源文件中,代码修改如下:

 #include "iostream.h"
#include "head.h"
int main()
{
#ifdef DEBUG
cout<< "Beginning execution of main()";
#endif
return ;
}

运行结果如下:Beginning execution of main()
Press any key to continue 
结论:通过使用#ifdef指示符,我们可以区隔一些与特定头文件、程序库和其他文件版本有关的代码。

================================================================================

为各个版本的软件升级工作是很困难的,因为这些补丁程序都是在一套软件的基础上不断地修改与扩充而编写的,并由不同的标志文件转入到不同的模块,虽然程序 体积在不断扩大,但丝毫不影响老用户的功能,这主要是得益于C程序的#ifdef/#else/#endif的作用。

我们主要使用以下几种方法,假设我们已在程序首部定义#ifdef DEBUG与#ifdef TEST:

1.利用#ifdef/#endif将某程序功能模块包括进去,以向某用户提供该功能。

  在程序首部定义#ifdef HNLD:

 #define HNLD

 #ifdef HNLD
#include"n166_hn.c"
#endif

  如果不许向别的用户提供该功能,则在编译之前将首部的HNLD加一下划线即可。

2.在每一个子程序前加上标记,以便追踪程序的运行。

 #ifdef DEBUG
  printf(" Now is in hunan !");
#endif

3.避开硬件的限制。有时一些具体应用环境的硬件不一样,但限于条件,本地缺乏这种设备,于是绕过硬件,直接写出预期结果。具体做法是:

 #ifndef TEST
  i=dial();  //程序调试运行时绕过此语句
#else
  i=;
#endif

调试通过后,再屏蔽TEST的定义并重新编译,即可发给用户使用了。

明白了之间的区别问题就变得非常的容易,修改上述代码只要把其中的#ifdef改成#if就可以达到目的。

#if 和#ifdef的区别的更多相关文章

  1. #if和#ifdef的区别

    学习STM32偶然发现:在Keil中直接预先定义宏USE_STDPERIPH_DRIVER,但是却没有指定宏的值.而在头文件中判断用的是如下代码: #ifdef USE_STDPERIPH_DRIVE ...

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

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

  3. darknet是如何对数据集做resize的?

    在准备数据集时,darknet并不要求我们预先对图片resize到固定的size. darknet自动帮我们做了图像的resize. darknet训练前处理 本文所指的darknet版本:https ...

  4. #ifdef 和 #if defined 的区别 -- 转

    #ifdef 和 #if defined 的区别在于,后者可以组成复杂的预编译条件,比如 #if defined (AAA) && defined (BBB) xxxxxxxxx #e ...

  5. #if 与 #ifdef 之间的区别

    先来看个例子: #define TARGET_LITTLE_ENDINA 1 #define TARGET_BIG_ENDINA 0 #ifdef TARGET_LITTLE_ENDINA call ...

  6. #ifdef 和 #if defined的区别

    #ifdef 和 #if defined的区别在于,后者可以组成复杂的预编译条件,比如 #if defined (AAA) && defined (BBB)xxxxxxxxx#endi ...

  7. #if、#ifdef、#if defined之间的区别【转】

    转自:http://quanminchaoren.iteye.com/blog/1870977 #if的使用说明 #if的后面接的是表达式 #if (MAX==10)||(MAX==20) code. ...

  8. C开发之----#if、#ifdef、#if defined之间的区别

    #if的使用说明 #if的后面接的是表达式 #if (MAX==10)||(MAX==20) code... #endif 它的作用是:如果(MAX==10)||(MAX==20)成立,那么编译器就会 ...

  9. #if和#ifdef区别

    #if  是要去判断, 跟值有关 #ifdef  只要定义了即可, 就会走下面的代码, 不管值是0还是1 所以一般都是用#ifdef DEBUG调试

随机推荐

  1. IP和端口查询

  2. 22 Extends 继承(子类、父类)

    本章主要介绍继承的 概念.方法重写(@Override注解的使用).使用场景.方法的执行顺序 /*1.继承的 概念 * 继承:多个类有共同的成员变量和成员方法,抽取到另外一个类中(父类),在让多个类去 ...

  3. "段落"组件:<p> —— 快应用组件库H-UI

     <import name="p" src="../Common/ui/h-ui/text/c_p"></import> <te ...

  4. Chrome浏览器架构

    通用浏览器架构 它可以是一个具有许多不同线程的进程,也可以是具有几个通过IPC进行通信的多个线程的进程. 一个具有许多不同线程的进程 通过IPC进行通信的多个线程的进程 注意 这些不同的体系结构是实现 ...

  5. 15.ASP.NET Core 应用程序中的静态文件中间件

    在这篇文章中,我将向大家介绍,如何使用中间件组件来处理静态文件.这篇文章中,我们讨论下面几个问题: 在ASP.NET Core中,我们需要把静态文件存放在哪里? 在ASP.NET Core中 wwwr ...

  6. java 的 数字、汉字 和 字母 的所占字节长度 与 字符长度 (邮件限制50个汉字)

    public static void main(String[] args) {  String a = "餿餿餿餿餿z";  byte[] bytes = a.getBytes( ...

  7. ConcurrentHashMap 同步安全 的真正含义(stringbuff 是同步安全的,stringbutter 不安全)

    同步安全的集合,在多线程下用到这个map是安全的,但这个安全指的是什么?线程安全指的是指get.remove.put等操作时即同一对象,同一时间只有一个线程能在这几个方法上运行,也就是说线程安全是在这 ...

  8. 数据结构和算法(Golang实现)(1)简单入门Golang-前言

    数据结构和算法在计算机科学里,有非常重要的地位.此系列文章尝试使用 Golang 编程语言来实现各种数据结构和算法,并且适当进行算法分析. 我们会先简单学习一下Golang,然后进入计算机程序世界的第 ...

  9. R - C Looooops POJ - 2115 (exgcd)

    题目大意:很好理解,一个for循环语句,从a开始到b结束,步长是c,模数是pow(2,k) 问,最少循环多少次,才能到达b,如果永远都到不了b,输出FOREVER 题解:其实就是求一个线性方程,cx= ...

  10. Python - 利用词云wordcloud,jieba和中国地图制作四大名著的热词图

    热词图很酷炫,也非常适合热点事件,抓住重点,以图文结合的方式表现出来,很有冲击力.下面这段代码是制作热词图的,用到了以下技术: jieba,把文本分词 wordcloud,制作热图 chardet,辨 ...