#define 用法整理

网络上资料里对 #define 的用法已经有很多的说明,在这里对现有的一些内容进行整理,希望能够对大家有帮助作用。

一、define的简单用法

1.简单的define定义

define MAXTIME 1000

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

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

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

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(它只是一个简单的替换),所以式子实际上变成了

ca + bd

另外举一个例子:

#define pin (int*);

pin a,b;

本意是a和b都是int型指针,但是实际上变成

int* a,b;

a是int型指针,而b是int型变量。这是应该使用typedef来代替define,这样a和b就都是int型指针了。所以我们在定义的时候,养成一个良好的习惯,建议所有的层次都要加括号。

3.宏的单行定义

#define Conn(x,y) x##y

#define ToChar(x) #@x

#define ToString(x) #x

x##y表示什么?表示x连接y,举例说:

int n = Conn(123,456); 结果就是 n=123456;

char str = Conn("asdf", "adf") 结果就是 str = "asdfadf";



再来看#@x,其实就是给x加上单引号,结果返回是一个const char。举例说:

char a = ToChar(1);结果就是a='1';

做个越界试验char a = ToChar(123);结果是a='3';

但是如果你的参数超过四个字符,编译器就给给你报错了!error C2015: too many characters in constant :P



最后看看#x,估计你也明白了,他是给x加双引号

char
str = ToString(123132); 结果就是 str="123132";

3.define的多行定义

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

define MACRO(arg1, arg2) do { \

/ declarations / \

stmt1; \

stmt2; \

/ ... / \

} while(0) / (no trailing ; ) /


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

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

如下:


#ifdef WINDOWS

......

......

#endif

#ifdef LINUX

......

......

#endif

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

5.如何定义宏、取消宏

//定义宏

#define [MacroName] [MacroValue]

//取消宏

#undef [MacroName]

普通宏

#define PI (3.1415926)

带参数的宏

#define max(a,b) ((a)>(b)? (a),(b))

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

6.条件编译

#ifdef XXX…(#else) …#endif

例如 #ifdef DV22_AUX_INPUT

#define AUX_MODE 3

#else

#define AUY_MODE 3

#endif

#ifndef XXX … (#else) … #endif

7.头文件(.h)可以被头文件或C文件包含;

重复包含(重复定义)

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

#ifndef headerfileXXX

#define headerfileXXX



文件内容



#endif

8.一些注意事项

1) 不能重复定义.除非定义完全相同.#define A(x) … 和#define A 是重复定义.

2) 可以只定义符号,不定义值.如#define AAA

二、define和typedef的区别

1) #define是预处理指令,在编译预处理时进行简单的替换,不作正确性检查,不关含义是否正确照样带入,只有在编译已被展开的源程序时才会发现可能的错误并报错。例如:

#define PI 3.1415926

程序中的:area=PIrr 会替换为3.1415926rr,如果你把#define语句中的数字9 写成字母g 预处理也照样带入。



2)typedef是在编译时处理的。它在自己的作用域内给一个已经存在的类型一个别名,但是You cannot use the typedef specifier inside a function definition。



3)typedef int * int_ptr;



#define int_ptr int

作用都是用int_ptr代表 int * ,但是二者不同,正如前面所说 ,#define在预处理 时进行简单的替换,而typedef不是简单替换 ,而是采用如同定义变量的方法那样来声明一种类型。也就是说;



//refer to (xzgyb(老达摩))

#define int_ptr int


int_ptr a, b; //相当于int * a, b; 只是简单的宏替换



typedef int int_ptr;

int_ptr a, b; //a, b 都为指向int的指针,typedef为int
引入了一个新的助记符



这也说明了为什么下面观点成立

//QunKangLi(维护成本与程序员的创造力的平方成正比)

typedef int * pint ;

#define PINT int *



那么:

const pint p ;//p不可更改,但p指向的内容可更改

const PINT p ;//p可更改,但是p指向的内容不可更改。



pint是一种指针类型 const pint p 就是把指针给锁住了 p不可更改,而const PINT p 是const int * p 锁的是指针p所指的对象。



3)也许您已经注意到#define 不是语句 不要在行末加分号,否则 会连分号一块置换。

三、#define和const的区别

1)差别:

const#define最大的差别在于:前者在堆栈分配了空间,而后者只是把具体数值直接传递到目标变量罢了。或者说,const的常量是一个Run-Time的概念,他在程序中确确实实的存在可以被调用、传递。而#define常量则是一个Compile-Time概念,它的生命周期止于编译期:在实际程序中他只是一个常数、一个命令中的参数,没有实际的存在。

const常量存在于程序的数据段.

#define常量存在于程序的代码段。

2)优缺点:

至于两者的优缺点,要看具体的情况了。一般的常数应用,我个人认为#define是一个更好的选择:

i.run-time的角度来看,他在空间上和时间上都有很好优势。

ii.compile-time的角度来看,类似m=t10的代码不会被编译器优化,t10的操作需要在run-time执行。而#define的常量会被合并。

但是:如果你需要粗鲁的修改常数的值,那就的使用const了,因为后者在程序中没有实际的存在.

另外在头文件中使用 #define 可以避免头文件重复包含的问题,这个功能,是const无法取代的。

四、#define和inline的区别

1.宏是代码处不加任何验证的简单替代,而内联函数是将代码直接插入调用处,而减少了普通函数调用时的资源消耗。

2.宏不是函数,只是在编译前预处理阶段将程序中有关字符串替换成宏体。

3.inline是函数,但在编译中不单独产生代码,而是将有关代码嵌入到调用处。

许多C程序员的经验表明,宏会为程序设计带来不小的安全隐患,许多由宏产生的问题就是实证。所以在C++中引入的const关键字以及inline函数可以完成与宏同样的功能,且更安全,更可靠。

参考链接列表:

http://www.cnblogs.com/minhost/archive/2009/01/07/1370806.html

http://www.cppblog.com/kerlw/archive/2007/04/20/22381.html

http://bbs.xml.org.cn/blog/more.asp?name=zhu_ruixian&id=23461

http://student.csdn.net/space.php?uid=100640&do=blog&id=26057
原文链接: https://www.cnblogs.com/gagexgy/archive/2011/05/16/2045301.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/25599

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月8日 上午3:25
下一篇 2023年2月8日 上午3:25

相关推荐