C语言宏定义##连接符和#符的使用

来源:互联网 发布:js 引用类型 编辑:程序博客网 时间:2024/04/28 23:34

部分内容转自:

http://blog.csdn.net/dotphoenix/article/details/4345174


看到之前大神的代码,很多地方都没看懂,还是感觉很厉害的样子,所以开始一点一点的看。先从基本的入手吧,看到一些宏定义就差了一下。


自定义的解析XML的类,有一些对@property的定义:

@property (nonatomic, property_attribute) property_type property_name; \

- (NSString*)class_name_of_##property_name;


#define TM_SERIALIZABLE_SYNTHESIZE(property_type, property_name) \

@synthesize property_name = _##property_name; \

- (NSString*)class_name_of_##property_name \

{ \

typeof(_##property_name) temp;\

temp = (property_type) _##property_name;\

return @#property_type; \

}


##的作用:

##被称为连接符(concatenator),用来将两个Token连接为一个Token。注意这里连接的对象是Token就行,而不一定 是宏的变量。比如你要做一个菜单项命令名和函数指针组成的结构体的数组,并且希望在函数名和菜单项命令名之间有直观的、名字上的关系。那么下面的代码就非常实用:

struct command{char * name;void (*function) (void);};#define COMMAND(NAME) { NAME, NAME ## _command }// 然后你就用一些预先定义好的命令来方便的初始化一个command结构的数组了:struct command commands[] = {COMMAND(quit),COMMAND(help),...}



就是连接参数和参数或者是参数和其他字符的功能。


顺便说下

#的作用:

在C语言的宏中,#的功能是将其后面的宏参数进行字符串化操作(Stringfication),简单说就是在对它所引用的宏变量 通过替换后在其左右各加上一个双引号。比如下面代码中的宏:


#define WARN_IF(EXP)    do{ if (EXP)    fprintf(stderr, "Warning: " #EXP "/n"); }   while(0)

那么实际使用中会出现下面所示的替换过程:

WARN_IF (divider == 0);被替换为do {if (divider == 0)fprintf(stderr, "Warning" "divider == 0" "/n");} while(0);

这样每次divider(除数)为0的时候便会在标准错误流上输出一个提示信息。


其他的方法就不转了,直接去原出处看吧。上面有连接。

其他的还有:

关于...的使用


错误的嵌套-Misnesting


由操作符优先级引起的问题-Operator Precedence Problem


消除多余的分号-Semicolon Swallowing


Duplication of Side Effects




0 0
原创粉丝点击