转自: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. 单芯片DP108USB声卡/音频解决方案完全替代CM108/CM108AH

    简介 DP108是一种高度集成的单芯片USB音频解决方案.所有重要的模拟模块嵌入DP108,包括双DAC和耳机放大器,ADC和麦克风助力器,锁相环,调节器,和USB收发器.许多功能与跳线或外部EEPR ...

  2. Java通过Http请求服务器

    Java通过Http请求服务器图片输出.下载.转换 Java开发过程中总会遇到从服务器中请求文件(图片.text文档等).此处详情记录从服务器下载图片的方法,以及以多种方式输出. 1.整体流程: 建立 ...

  3. 拓扑排序入门详解&&Educational Codeforces Round 72 (Rated for Div. 2)-----D

    https://codeforces.com/contest/1217 D:给定一个有向图,给图染色,使图中的环不只由一种颜色构成,输出每一条边的颜色 不成环的边全部用1染色 ps:最后输出需要注意, ...

  4. leetcode c++做题思路和题解(5)——堆的例题和总结

    堆和优先队列 堆的简介, 是一种二叉树, 有最大堆和最小堆miniheap. 通常用于构建优先队列. 0. 目录 数据流中的第K大元素 1. 数据流中的第K大元素 数据流中的第K大元素 复杂度为log ...

  5. Linux C++ 网络编程学习系列(3)——多路IO之poll实现

    poll实现多路IO 源码地址:https://github.com/whuwzp/linuxc/tree/master/poll 源码说明: server.cpp: 监听127.1:6666,功能是 ...

  6. 006-循环结构(下)-C语言笔记

    006-循环结构(下)-C语言笔记 学习目标 1.[掌握]do-while循环结构 2.[掌握]for循环结构 3.[掌握]嵌套循环 一.do-while循环结构 do-while语法:   1 2 ...

  7. python初学(三)

    1.以软科中国最好大学排名为分析对象,基于requests库和bs4库编写爬虫程序,对2015年至2019年间的中国大学排名数据进行爬取,并按照排名先后顺序输出不同年份的前10位大学信息,要求对输出结 ...

  8. Rescue BFS+优先队列 杭电1242

    思路 : 优先队列 每次都取最小的时间,遇到了终点直接就输出 #include<iostream> #include<queue> #include<cstring> ...

  9. .Net Core Send Email

    1.安装Nuget包MailKit,引用命名空间. using MailKit.Net.Smtp; using MimeKit; 注意:引用MailKit对应最新版本 2.定义收发地址和标题 Mime ...

  10. Springboot:JSR303数据校验(五)

    @Validated //开启JSR303数据校验注解 校验规则如下: [一]空检查 @Null 验证对象是否为null @NotNull 验证对象是否不为null, 无法查检长度为0的字符串 @No ...