#define的用法体会

#define 创建一个宏,该宏是标识符或参数化标识符与标记字符串的关联。 在定义宏之后,编译器可用标记字符串替换源文件中标识符的每个匹配项。

语法

#define identifier token-string

#define identifier ( identifier 1 , ... , identifier n ) token-string

备注

1 #define 指令促使编译器用 token-string 替换源文件中 identifier 的每个匹配项。 仅当 identifier 构成标记时才替换它。 也就是说,如果 identifier 出现在注释、字符串或较长的标识符中,则不会替换它。

2 第二种形式类似于函数,例如

#define mul(a,b) (a*b) 形参名称将出现在 token-string 中以标记实际值的替换位置。

token-string 中前面未带stringizing (#)、charizing(#@)
或 token-pasting (##) 运算符或后面未跟 ## 运算符的每个形参将由对应的实参替换。

注意:

1 宏就是简单的字符替换,注意替换后的运算符优先级可能会影响宏定义所要表达的。所以要善于使用小括号。例如:

#define Add(a,b) a+b  如果使用的时候:2*Add(1,2) 原本想让它等于6,但替换后变成2*1+2=4。所以要注意。

2 #define中的换行符是反斜杠\。如果一行没写完,直接加一个\,下一行继续写就可以了。

3 注意这里只是字符替换,宏定义中不应含有return等语句,想一想替换后,会变成什么样子。

宏的返回值的两种形式:

1 操作符。

#define Max(a,b) (((a)>(b))(a):(b))

#define add(a,b) ((a)+(b))

2 将返回值赋值给一个额外的形参,这个形参就是返回值。

#define cal(a,b,c) {c=a+b;}

一个非常有意思的例子:

定义一个求最大值的宏。

可能会这么写:#define Max(a,b) ((a)>(b) ?a):(b))

这么做可能对于大多数情况是没有错误的,但是其实这么做是不严谨的。例如:

#define Max(a,b) ((a)>(b)? (a):(b))

int fun(int *a)

{

*a=*a+1;

return *a;

}

main()

{

int a=1,b=2,c;

c=Max(a,fun(&b));

}//我们想得到的c的值应该是3,但实际会发现c的值是4.

因为首先我们替换:c=((a)>(fun(&b))? (a):(fun(&b)));

可以发现fun执行了两次,b的值加了两次变成了4.所以结果是4.

这里给出一个严谨的做法:

使得参数只被执行一次。

#define Max(a,b) ({\

typeof(a) _a=(a);\

typeof(b) _b=(b);\

(_a>_b)? _x : _y; })

这样就不会有上述的问题了。

注意:({...})的作用是将内部的几条语句中最后一条的值返回,它也允许在内部声明变量(因为它通过大括号组成了一个局部Scope)。用此可以达到return的目的。

!!注:这里使用了typeof,它是c的一个新扩展。而在vs2005,2010,2013中都无法使用。只能在在线编译器下执行,结果是对的。

观察发现:vs中不识别关键字typeof了。在C++中可用decltype实现相似功能,求某个变量的类型。而且vs中也不可以有这样的({...})的东西了。要么#define..
() 要么#define .. {}。

所以上面的做法可以改成:

#define MIN(X,Y,M) {\

decltype(X)x_ = (X);\

decltype(Y)y_ = (Y);\

M=(x_ < y_) ? x_ : y_; }

使用时:int a=1,b=2,c; Max(a,b,c);c为返回值,不参与运算。

#与##与#@在#define中的用法:

#的意思是不展开参数

如果在token-string  中出现以#开头,意思是:不展开参数,直接替换。

如果在token-string  中出现不以#开头,意思是:展开参数,直接替换。

例如:

#define f(a) a+1

#define T(a) #a

#define H(a) a

T(f(a))->f(a)->a+1

H(f(a))->H(a+1)->a+1

虽然结果一样,但是过程不一样。

##的意思是字符串连接符

例如:

#define f(a,b) a##b##lobe

结果就是ablobe

注意:##不能出现在开头,也不能出现在结尾。只能出现在中间。

#@字符化运算符

Microsoft 专用

charizing 运算符只能与宏的参数一起使用。 如果宏的定义中的形参前有 #@,则会在扩展宏时用单引号括起实参并将其视为一个字符。

#define makechar(x)  #@x

==

char a= makechar(x);

例如:

#define H(x) #@x

cout<<H(a)<<endl;

输出结果:a

cout<<H(ab)<<endl;

输出结果:24930

注解:就是相当于把#@后面的实参变成一个字符型的字符。

时间: 2024-11-01 01:00:16

#define的用法体会的相关文章

typedef和#define的用法与区别

一.typedef的用法 在C/C++语言中,typedef常用来定义一个标识符及关键字的别名,它是语言编译过程的一部分,但它并不实际分配内存空间,实例像: typedef    int       INT;typedef    int       ARRAY[10];typedef   (int*)   pINT; typedef可以增强程序的可读性,以及标识符的灵活性,但它也有“非直观性”等缺点. 二.#define的用法 #define为一宏定义语句,通常用它来定义常量(包括无参量与带参量

C语言 typedef和#define的用法与区别

typedef和#define的用法与区别 一.typedef的用法 在C/C++语言中,typedef常用来定义一个标识符及关键字的别名,它是语言编译过程的一部分,但它并不实际分配内存空间,实例像: typedef    int       INT;typedef    int       ARRAY[10];typedef   (int*)   pINT; typedef可以增强程序的可读性,以及标识符的灵活性,但它也有“非直观性”等缺点. 二.#define的用法 #define为一宏定义

(转)typedef和#define的用法与区别

typedef和#define的用法与区别 一.typedef的用法 在C/C++语言中,typedef常用来定义一个标识符及关键字的别名,它是语言编译过程的一部分,但它并不实际分配内存空间,实例像: typedef    int       INT; typedef    int       ARRAY[10]; typedef   (int*)   pINT; typedef可以增强程序的可读性,以及标识符的灵活性,但它也有“非直观性”等缺点. 二.#define的用法 #define为一宏

C语言中#define的用法(转)

今天整理了一些#define的用法,与大家共享! 1.简单的define定义 #define MAXTIME 1000 一个简单的MAXTIME就定义好了,它代表1000,如果在程序里面写 if(i<MAXTIME){.........} 编译器在处理这个代码之前会对MAXTIME进行处理替换为1000. 这样的定义看起来类似于普通的常量定义CONST,但也有着不同,因为define的定义更像是简单的文本替换,而不是作为一个量来使用,这个问题在下面反映的尤为突出. 2.define的“函数定义”

【转】typedef和#define的用法与区别

typedef和#define的用法与区别 一.typedef的用法 在C/C++语言中,typedef常用来定义一个标识符及关键字的别名,它是语言编译过程的一部分,但它并不实际分配内存空间,实例像: typedef int INT; typedef int ARRAY[10]; typedef (int*) pINT; typedef可以增强程序的可读性,以及标识符的灵活性,但它也有"非直观性"等缺点. 二.#define的用法 #define为一宏定义语句,通常用它来定义常量(包括

#define的用法

#define N 100  ok#define N 100; error#define N = 100  error   int a[N] => int a[= 100] error#define pin int*   pin a,b; error(a为int*,b为int) 2. 特殊用法 #define BEGIN {#define END } int main BEGIN    printf("haha");END 定义一个循环#define LOOP for(;;) 重

c++ define的用法(转)

#define是C语言中提供的宏定义命令,其主要目的是为程序员在编程时提供一定的方便,并能在一定程度上提高程序的运行效率,但学生在学习时往往不能 理解该命令的本质,总是在此处产生一些困惑,在编程时误用该命令,使得程序的运行与预期的目的不一致,或者在读别人写的程序时,把运行结果理解错误,这对 C语言的学习很不利.1 #define命令剖析1.1 #define的概念#define命令是C语言中的一个宏定义命令,它用来将一个标识符定义为一个字符串,该标识符被称为宏名,被定义的字符串称为替换文本.该命

define的用法与注意事项

#define是C语言中提供的宏定义命令,其主要目的是为程序员在编程时提供一定的方便,并能在一定程度上提高程序的运行效率,但在学习时往往不能理解该命令的本质,总是在此处产生一些困惑,在编程时误用该命令,使得程序的运行与预期的目的不一致,或者在读别人写的程序时,把运行结果理解错误,这对C语言的学习很不利.下面将分别对基本用法和特殊做详细介绍. 一.#define的基本用法1 #define命令剖析1.1   #define的概念#define命令是C语言中的一个宏定义命令,它用来将一个标识符定义为

typedef&amp;define的用法与区别

1.  typedef typedef故名思意就是类型定义的意思,但是它并不是定义一个新的类型而是给已有的类型起一个别名,在这一点上与引用的含义类似,引用是变量或对象的别名,而typedef定义的是类型的别名.typedef的作用主要有两点: 1.1  简化复杂的类型声明 简化复杂的类型声明,或给已有类型起一含义明确的别名:如: typedef bool (*FuncPointer)(int, double); //声明了一个返回 bool 类型并带有两个(int和double)形参的函数的指针