C/C++预处理指令#define,#ifdef,#ifndef,#endif…

来源:互联网 发布:windows loader 2.4 编辑:程序博客网 时间:2024/05/29 09:17

转载请标明出处:http://blog.csdn.net/xx326664162/article/details/53463205 文章出自:薛瑄的博客

这篇文章都是概念性知识,没有什么可分析,完全转载原作者,方便以后查询。

工作中经常这样使用宏:

1、 常常使用宏来调试代码:

#if 0///< 旧的代码(或函数) (旧的代码, 将会被预处理的时候,屏蔽掉, 不进行编译)#else///< 新的代码(或函数)#endif#ifndef JOE_DEBUG///< 新的代码(或函数)#else///< 旧的代码(或函数) (旧的代码, 将会被预处理的时候,屏蔽掉, 不进行编译)#endif#ifdef Q_DEBUG///< 新的代码(或函数)#else///< 旧的代码(或函数) (旧的代码, 将会被预处理的时候,屏蔽掉, 不进行编译)#endif<br><br>

通过以上类似的方法, 可以防止由于过多的修改代码, 而把代码修改的一塌糊涂. 建议修改代码的时候, 做到保护好以前的代码, 尽量不进行代码的删除操作. 切记, 能不删除, 就不删除…不要养成随手就删除的习惯. 要养成使用宏和注释代码的习惯.

2、 使用宏来根据不同的平台包含不同的文件. 很多时候, 我们的代码是需要跨系统平台编译和运行的. 比如: 一个小功能代码, 需要既可以在Win下面运行, 还要可以在Max, linux上面运行. 可是, 因为系统的不一样, 有些时候, 头文件的包含的名字是不一样的. 所以,这时候, 就是用到了宏. 因为我们使用编程工具分不同的系统平台, 编程工具自身的环境就会包含不同平台的系统宏, 假设OS_Win, OS_Mac, OS_Linux 分别代码三种系统不同的宏. 而且,Win版本的编程工具中已经定义了OS_Win, 类似的Mac下, 编程工具定义的是OS_Mac, Linux…

#ifdef OS_Win#include <windows.h>#endif#ifdef OS_Mac#include <mac.h>#endif#ifdef OS_Linux#include <linux.h>#endif/** 不仅使用在头文件的包含. 而且,对于不同的系统平台. 你也可以使用不同的代码结构. */

3、 接着就是宏定义了. 使用宏来定义一些常量, 表达式…详细内容, 见下面

本文主要记录了C/C++预处理指令,常见的预处理指令如下:

  1. #空指令,无任何效果
  2. #include包含一个源代码文件
  3. #define定义宏
  4. #undef取消已定义的宏
  5. #if如果给定条件为真,则编译下面代码
  6. #ifdef如果宏已经定义,则编译下面代码
  7. #ifndef如果宏没有定义,则编译下面代码
  8. #elif如果前面的#if给定条件不为真,当前条件为真,则编译下面代码
  9. #endif结束一个#if……#else条件编译块
  10. #error停止编译并显示错误信息

本来只是想了解一下#ifdef,#ifndef,#endif的,没想到查出来这么多的预处理指令,上面的多数都是常见的,但是平时没有怎么注意预处理这方面的内容,所以这里梳理一下知识吧。同时有什么不妥的地方,或者遗漏了什么内容,还请留言指出。

什么是预处理指令?

预处理指令是以#号开头的代码行。#号必须是该行除了任何空白字符外的第一个字符。#后是指令关键字,在关键字和#号之间允许存在任意个数的空白字符。整行语句构成了一条预处理指令,该指令将在编译器进行编译之前对源代码做某些转换。

以前没有在意的学者注意了,预处理指令是在编译器进行编译之前进行的操作.预处理过程扫描源代码,对其进行初步的转换,产生新的源代码提供给编译器。可见预处理过程先于编译器对源代码进行处理。在很多编程语言中,并没有任何内在的机制来完成如下一些功能:在编译时包含其他源文件、定义宏、根据条件决定编译时是否包含某些代码(防止重复包含某些文件)。要完成这些工作,就需要使用预处理程序。尽管在目前绝大多数编译器都包含了预处理程序,但通常认为它们是独立于编译器的。预处理过程读入源代码,检查包含预处理指令的语句和宏定义,并对源代码进行响应的转换。预处理过程还会删除程序中的注释和多余的空白字符。

#include包含一个源代码文件

这个预处理指令,我想是见得最多的一个,简单说一下,第一种方法是用尖括号把头文件括起来。这种格式告诉预处理程序在编译器自带的或外部库的头文件中搜索被包含的头文件。第二种方法是用双引号把头文件括起来。这种格式告诉预处理程序在当前被编译的应用程序的源代码文件中搜索被包含的头文件,如果找不到,再搜索编译器自带的头文件。采用两种不同包含格式的理由在于,编译器是安装在公共子目录下的,而被编译的应用程序是在它们自己的私有子目录下的。一个应用程序既包含编译器提供的公共头文件,也包含自定义的私有头文件。采用两种不同的包含格式使得编译器能够在很多头文件中区别出一组公共的头文件。

#define定义宏

有关#define这个宏定义,在C语言中使用的很多,因为#define存在一些不足,C++强调使用const来定义常量。宏定义了一个代表特定内容的标识符。预处理过程会把源代码中出现的宏标识符替换成宏定义时的值。记住仅仅是进行标识符的替换。下面列举一些#define的使用:

1、 用#define实现求最大值和最小值的宏

#include <stdio.h>#define MAX(x,y) (((x)>(y))?(x):(y))#define MIN(x,y) (((x)<(y))?(x):(y))int main(void){#ifdef MAX    //判断这个宏是否被定义    printf("3 and 5 the max is:%d\n",MAX(3,5));#endif#ifdef MIN    printf("3 and 5 the min is:%d\n",MIN(3,5));#endif    return 0;}/* * (1)三元运算符要比if,else效率高 * (2)宏的使用一定要细心,需要把参数小心的用括号括起来, * 因为宏只是简单的文本替换,不注意,容易引起歧义错误。*/

2、宏定义的错误使用

#include <stdio.h>#define SQR(x) (x*x)int main(void){    int b=3;#ifdef SQR//只需要宏名就可以了,不需要参数,有参数的话会警告    printf("a = %d\n",SQR(b+2));#endif    return 0;}/* *首先说明,这个宏的定义是错误的。并没有实现程序中的B+2的平方 * 预处理的时候,替换成如下的结果:b+2*b+2 * 正确的宏定义应该是:#define SQR(x) ((x)*(x)) * 所以,尽量使用小括号,将参数括起来。*/

3、宏参数的连接

#include <stdio.h>#define STR(s) #s#define CONS(a,b) (int)(a##e##b)int main(void){#ifdef STR    printf(STR(VCK));#endif#ifdef CONS    printf("\n%d\n",CONS(2,3));#endif    return 0;}/* (绝大多数是使用不到这些的,使用到的话,查看手册就可以了) * 第一个宏,用#把参数转化为一个字符串 * 第二个宏,用##把2个宏参数粘合在一起,及aeb,2e3也就是2000*/

4、用宏得到一个字的高位或低位的字节

#include <stdio.h>#define WORD_LO(xxx) ((byte)((word)(xxx) & 255))#define WORD_HI(xxx) ((byte)((word)(xxx) >> 8))int main(void){    return 0;}/* * 一个字2个字节,获得低字节(低8位),与255(0000,0000,1111,1111)按位相与 * 获得高字节(高8位),右移8位即可。*/

5、用宏定义得到一个数组所含元素的个数

#include <stdio.h>#define ARR_SIZE(a) (sizeof((a))/sizeof((a[0])))int main(void){    int array[100];#ifdef ARR_SIZE    printf("array has %d items.\n",ARR_SIZE(array));#endif    return 0;}/* *总的大小除以每个类型的大小 */

其他一些指令

#error指令将使编译器显示一条错误信息,然后停止编译。
#line指令可以改变编译器用来指出警告和错误信息的文件号和行号。
#pragma指令没有正式的定义。编译器可以自定义其用途。典型的用法是禁止或允许某些烦人的警告信息。

转载:C/C++预处理指令#define,#ifdef,#ifndef,#endif…

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 红米4a开不了机怎么办 魅族手机拨打电话时黑屏怎么办 金立手机拨打电话时黑屏怎么办 红米手机刷机黑屏了怎么办 酷派手机开机黑屏但能嗡嗡响怎么办 酷派手机忘记锁屏密码怎么办 酷派手机锁屏密码忘了怎么办 酷派手机不停的开机关机怎么办 苹果6手机进水了开不了机怎么办 金立手机突然黑屏开不了机怎么办 丢失手机又忘了ID锁怎么办? 小米2按出电话后黑屏怎么办 华为手机桌面拨号键没有了怎么办 华为荣耀5x黑屏后无法关机怎么办 华为手机突然黑屏电池充不了怎么办 华为手机恢复出厂设置后黑屏怎么办 华为荣耀畅玩6a内存不够怎么办 红米note4玩王者荣耀卡怎么办 华为荣耀5a手机被锁怎么办 华为荣耀v8应用锁忘记蜜码怎么办 阿里巴巴一键代销被投诉受假怎么办 登录小米云服务怎么删除密码怎么办 苹果6云空间连接不上怎么办 买家收到淘宝网交易异常通知怎么办 快递把我秒杀的货弄丢了怎么办 手机淘宝退货物流单号填错了怎么办 买家要求退货退款但是不发货怎么办 多给买家寄包裹不接电话怎么办 给买家发货物流单号错了怎么办 淘宝退货退款快递单号填错了怎么办 淘宝不小心点了延迟收货怎么办 淘宝快递地址错了货已经发了怎么办 卖家送运费险买家填错单号怎么办 买家无赖点了延迟收货卖家怎么办 淘宝卖家快递单号填错了怎么办 淘宝店有当天的快递忘记发货怎么办 在美国官网买东西少寄了东西怎么办 闲鱼退货货收了不退钱怎么办 闲鱼退货卖家收到东西不退钱怎么办 淘宝店铺物流服务给差评怎么办 在合肥东方融资网被骗了怎么办