#ifndef、#def、#endif等宏是什么意思

基础很重要,偶开始补习基础了,每天多会写点上来。。。。

一般情况下,源程序中所有的行都参加编译。但是有时希望对其中一部分内容只在满足一定条件才进行编译,也就是对一部分内容指定编译的条件,这就是“条件编译”。有时,希望当满足某条件时对一组语句进行编译,而当条件不满足时则编译另一组语句。
条件编译命令最常见的形式为:
    #ifdef 标识符
    程序段1
    #else
    程序段2
    #endif
    
    它的作用是:当标识符已经被定义过(一般是用#define命令定义),则对程序段1进行编译,否则编译程序段2。
    其中#else部分也可以没有,即:
    #ifdef
    程序段1
    #denif
    
    这里的“程序段”可以是语句组,也可以是命令行。这种条件编译可以提高C源程序的通用性。如果一个C源程序在不同计算机系统上系统上运行,而不同的计算机又有一定的差异。例如,我们有一个数据类型,在Windows平台中,应该使用long类型表示,而在其他平台应该使用float表示,这样往往需要对源程序作必要的修改,这就降低了程序的通用性。可以用以下的条件编译:
    #ifdef WINDOWS
    #define MYTYPE long
    #else
    #define MYTYPE float
    #endif
    
    如果在Windows上编译程序,则可以在程序的开始加上
    #define WINDOWS
    
    这样则编译下面的命令行:
    #define MYTYPE long
    
    如果在这组条件编译命令之前曾出现以下命令行:
    #define WINDOWS 0
    
    则预编译后程序中的MYTYPE都用float代替。这样,源程序可以不必作任何修改就可以用于不同类型的计算机系统。当然以上介绍的只是一种简单的情况,可以根据此思路设计出其它的条件编译。
    例如,在调试程序时,常常希望输出一些所需的信息,而在调试完成后不再输出这些信息。可以在源程序中插入以下的条件编译段:
    #ifdef DEBUG
    print ("device_open(%p)/n", file);
    #endif
    
    如果在它的前面有以下命令行:
    #define DEBUG
    
    则在程序运行时输出file指针的值,以便调试分析。调试完成后只需将这个define命令行删除即可。有人可能觉得不用条件编译也可达此目的,即在调试时加一批printf语句,调试后一一将printf语句删除去。的确,这是可以的。但是,当调试时加的printf语句比较多时,修改的工作量是很大的。用条件编译,则不必一一删改printf语句,只需删除前面的一条“#define DEBUG”命令即可,这时所有的用DEBUG作标识符的条件编译段都使其中的printf语句不起作用,即起统一控制的作用,如同一个“开关”一样。
    有时也采用下面的形式:
    #ifndef 标识符
    程序段1
    #else
    程序段2
    #endif
    
    只是第一行与第一种形式不同:将“ifdef”改为“ifndef”。它的作用是:若标识符未被定义则编译程序段1,否则编译程序段2。这种形式与第一种形式的作用相反。
    以上两种形式用法差不多,根据需要任选一种,视方便而定。
    还有一种形式,就是#if后面的是一个表达式,而不是一个简单的标识符:
    #if 表达式
    程序段1
    #else
    程序段2
    #endif
    
    它的作用是:当指定的表达式值为真(非零)时就编译程序段1,否则编译程序段2。可以事先给定一定条件,使程序在不同的条件下执行不同的功能。
    例如:输入一行字母字符,根据需要设置条件编译,使之能将字母全改为大写输出,或全改为小写字母输出。
    #define LETTER 1
    main()
    {
    char str[20]="C Language",c;
    int i=0;
    while((c=str[i])!='/0'){
    i++;
    #if LETTER
    if(c>='a'&&c<='z') c=c-32;
    #else
    if(c>='A'&&c<='Z') c=c+32;
    #endif
    printf("%c",c);
    }
    }
    
    运行结果为:C LANGUAGE
    现在先定义LETTER为1,这样在预处理条件编译命令时,由于LETTER为真(非零),则对第一个if语句进行编译,运行时使小写字母变大写。如果将程序第一行改为:
    #define LETTER 0
    
    则在预处理时,对第二个if语句进行编译处理,使大写字母变成小写字母(大写字母与相应的小写字母的ASCII代码差32)。此时运行情况为:
    c language
    有人会问:不用条件编译命令而直接用if语句也能达到要求,用条件编译命令有什么好处呢?的确,此问题完全可以不用条件编译处理,但那样做目标程序长(因为所有语句都编译),而采用条件编译,可以减少被编译的语句,从而减少目标的长度。当条件编译段比较多时,目标程序长度可以大大减少。

#ifndef、#def、#endif等宏是什么意思相关推荐

  1. C语言中的#ifndef、#def、#endif等宏

        #ifndef x #define x ... #endif 这是宏定义的一种,它可以根据是否已经定义了一个变量来进行分支选择,一般用于调试等等.实际上确切的说这应该是预处理功能中三种(宏定义 ...

  2. c:#ifndef, #define, #endif 作用

    #ifndef, #define, #endif 作用 #ifndef 它是if not define 的简写,是宏定义的一种,实际上确切的说,这应该是预处理功能三种(宏定义.文件包含.条件编译)中的 ...

  3. [Windows编程] #pragma once 和#ifndef ... #define ... #endif 比较

    C++中防止头文件被多次include 的常见方式有: 1) 用#ifndef ...  #define ... #endif  宏 #ifndef __MYHEADER_H__ #define __ ...

  4. #pragma once与#ifndef #define ...#endif的区别

    1. #pragma once用来防止某个头文件被多次include: #ifndef,#define,#endif用来防止某个宏被多次定义. 2. #pragma once是编译相关,就是说这个编译 ...

  5. 【转载】#pragma once与#ifndef #define #endif的区别

    一.相同点         两者的共同点都是为了避免同一个文件被 include 多次,但是 #ifndef #define #endif 不只有这个作用.  在能够支持这两种方式的编译器上,二者并没 ...

  6. 条件编译用法(#ifndef #define #endif#else)

    1. 文件中的#ifndef 头件的中的#ifndef,这是一个很关键的东西.比如你有两个C文件,这两个C文件都include了同一个头文件.而编译时,这两个C文件要一同编译成一个可运行文件,于是问题 ...

  7. #ifndef#define#endif的用法

    你所遇到的这几个宏是为了进行条件编译.一般情况下,源程序中所有的行都参加编译.但是有时希望对其中一部分内容只在满足一定条件才进行编译,也就是对一部分内容指定编译的条件,这就是"条件编译&qu ...

  8. #pragma once 和 #ifndef ... #define ... #endif 的区别

    这两者都是为了防止文件被包含多次.但是有些细微的区别: 1,来源的区别:#pragma once 是编译系统相关的,由编译器提供.而#ifndef ...#define ... #endif 是c/c ...

  9. #ifndef #define #endif 和#pragma once的区别

    相同点:#ifndef #define #endif 和 #pragma once 都是用来保证一个.h文件只被编译一次. 不同点: 1. #ifndef #define #endif 用来防止一个宏 ...

最新文章

  1. mysql 显示用户_在Mysql中如何显示所有用户?
  2. 通达oa与mysql集成_安装通达OA后想使用其自带的Mysql数据库的解决方法
  3. WIN7重装IE的步骤
  4. Win10调试ssd_tensorflow的目标检测
  5. 【中级】【后台】 微信小程序 - 腾讯云 - wafer2 - PHP - DEMO - 003 - 源码分析 - 03 - 腾讯后台初始化 和 CodeIgniter
  6. ios ffmpeg(libfdk-aac) aac encode
  7. 力扣-628 三个数的最大乘积
  8. web安全day21:学习使用最基本的批处理程序
  9. [洛谷P2370]yyy2015c01的U盘
  10. java opencv 摄像头,OpenCV使用摄像头
  11. 太阳方位角/天顶角名词解释及计算方法
  12. tcpdump抓取网络
  13. 手把手教你Photoshop蒙版的使用(二)
  14. ddr走线教程_DDR走线规则
  15. IIS配置Web服务
  16. windows server上重启IIS命令
  17. 广联达安装电气桥架电缆布置要点
  18. Windows Server 2012 域控服务器连接转换服务器实现office服务功能
  19. Fastadmin开源CRM客户管理系统融合开发呼叫中心系统
  20. MySQL Navicat Premium 保存的SQL在哪里?

热门文章

  1. 最优化学习笔记(十二)——基本共轭方向算法(续)
  2. B端产品设计——批量导入
  3. 公司为什么宁愿花11K月薪招新人,也不愿意花9K的月薪留住老员工?
  4. 在阿里巴巴工作是一种怎样的体验?
  5. 预见2021-罗兰贝格中国行业趋势报告
  6. 产品新人没有完整项目经验?这篇文章帮你打开思路
  7. python queue的用法_python Queue模块使用
  8. 虚拟专题:知识图谱 | 医学知识图谱构建关键技术及研究进展
  9. 区域卫生数据用于临床疗效分析的可用性研究
  10. 【OJ】洛谷排序题单题解锦集