#define 以及与typedef 、 inline的区别

什么是define

宏定义,简单的理解就是替换,其实这也是本质。如果熟悉g++编译过程的话,会了解到一个概念叫做预处理,就是在编译之前做个处理。这个过程并不像编译那么复杂,就是简单的递归替换和删除。替换的就是宏定义和include文件,删除注释。注意这里我们谈到一个概念,递归替换,这个其实是很常见的,比如你的程序中include一个.h文件,但是这个.h文件中还引入了另一个.h文件,那么这个时候就需要进行递归替换。

 

1.简单的define定义

#define MAXTIME 1000

一个简单的MAXTIME就定义好了,它代表1000,如果在程序里面写

if(i<MAXTIME){.........}

编译器在处理这个代码之前会对MAXTIME进行处理替换为1000。

这样的定义看起来类似于普通的常量定义CONST,但也有着不同,因为define的定义更像是简单的文本替换,而不是作为一个量来使用,这个问题在下面反映的尤为突出。

 

2.define的“函数定义”

define可以像函数那样接受一些参数,如下

#define max(x,y) (x)>(y)?(x):(y);

这个定义就将返回两个数中较大的那个,看到了吗?因为这个“函数”没有类型检查,就好像一个函数模板似的,当然,它绝对没有模板那么安全就是了。可以作为一个简单的模板来使用而已。

但是这样做的话存在隐患,例子如下:

#define Add(a,b) a+b;

在一般使用的时候是没有问题的,但是如果遇到如:c * Add(a,b) * d的时候就会出现问题,代数式的本意是a+b然后去和c,d相乘,但是因为使用了define(它只是一个简单的替换),所以式子实际上变成了

c*a + b*d

另外举一个例子:

#define pin (int*);
pin a,b;

本意是a和b都是int型指针,但是实际上变成int* a,b;
a是int型指针,而b是int型变量。
这是应该使用typedef来代替define,这样a和b就都是int型指针了。

所以我们在定义的时候,养成一个良好的习惯,建议所有的层次都要加括号。

 

3.宏的单行定义

#define A(x) T_##x
#define B(x) #@x

#define C(x) #x

我们假设:x=1,则有:

A(1)------〉T_1
B(1)------〉'1'
C(1)------〉"1"

 

4.define的多行定义

define可以替代多行的代码,例如MFC中的宏定义:

#define MACRO(arg1, arg2) do { /
/* declarations */ /
stmt1; /
stmt2; /
/* ... */ /
} while(0) /* (no trailing ; ) */


关键是要在每一个换行的时候加上一个"/"

 

5.在大规模的开发过程中,特别是跨平台和系统的软件里,define最重要的功能是条件编译。

#ifdef WINDOWS
......
......
#endif
#ifdef LINUX
......
......
#endif

可以在编译的时候通过#define设置编译环境

 

6.如何定义宏、取消宏

//定义宏
#define [MacroName] [MacroValue]

//取消宏
#undef [MacroName]

//普通宏
#define PI (3.1415926)

//带参数的宏
#define max(a,b) ((a)>(b)? (a),(b))

关键是十分容易产生错误,包括机器和人理解上的差异等等。

 

7.条件编译

#ifdef XXX…(#else) …#endif

 

例如

#ifdef DV22_AUX_INPUT
#define AUX_MODE 3
#else
#define AUY_MODE 3
#endif
#ifndef XXX … (#else) … #endif

 

8.头文件(.h)可以被头文件或C文件包含
重复包含(重复定义)
由于头文件包含可以嵌套,那么C文件就有可能包含多次同一个头文件,就可能出现重复定义的问题的。
通过条件编译开关来避免重复包含(重复定义)
例如

#ifndef __headerfileXXX__
#define __headerfileXXX__
…
//文件内容
…
#endif

 

下面我们将c++ 常用的宏定义罗列一下:

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

 

#define和别名typedef的区别

1) 执行时间不同,typedef在编译阶段有效,typedef有类型检查的功能;#define是宏定义,发生在预处理阶段,不进行类型检查;

2) 功能差异,typedef 用来定义类型的别名,定义与平台无关的数据类型,与 struct的结合使用等。#define不只是可以为类型取别名,还可以定义常量、变量、编译开关等。

3) 作用域不同,#define没有作用域的限制,只要是之前预定义过的宏,在以后的程序中都可以使用。而typedef有自己的作用域。

#define与inline的区别

1) #define是关键字,inline是函数;

2) 宏定义在预处理阶段进行文本替换,inline函数在编译阶段进行替换;

3) inline函数有类型检查,相比宏定义比较安全;

posted @ 2021-08-30 10:22  默行于世  阅读(86)  评论(0编辑  收藏  举报