C语言-特殊的宏#与##

177 阅读1分钟

#:字符串化

可以用在断言中,如果断言失败,则输出到反馈信息中(echo > err.msg) 

When you put a # before an argument in a preprocessor macro, the preprocessor turns that argument into a character array. This, combined with the fact that character arrays with no intervening punctuation are concatenated into a single character array, allows you to make a very convenient macro for printing the values of variables during debugging

www.cnblogs.com/Anker/p/341…

blog.csdn.net/dotphoenix/…

When you put a # before an argument in a preprocessor macro, the preprocessor turns that argument into a character array.

**注意:#**宏的参数会被直接转换并不会递归展开,这是它与其他带参宏的不同

案例

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

// ** user code ** //
​int err_module = 0;
WARN_IF(err_module == 0);
IntTostring(err_module);

//输出
Warning: err_module == 0
err_module

##:连接左右符号

在宏体中,如果宏体所在标示符中有##,那么在宏体扩展的时候,宏参数会被直接替换到标示符中。(转者注:这里的宏参数会展开一次,但是并不会递归展开.对宏体中的参数替换一次,然后强制链接)

hbprotoss.github.io/post/cyu-ya…

案例

// 1.基础用法

#define WhatAFuckDay 555
#define Type1(type, name) type _name  ## name_ ## WhatAFuckDay
#define Type2(type, name) type _name  ## name_
#define Type3(type, name) type _name_ ## name

// ** user code ** //
Type1(int, c); // int _namename_WhatAFuckDay;
Type1(int, c); // int _namename_;
Type2(int, c); // int _name_c;

_namename_WhatAFuckDay = 1;
_namename_ = 2;
_name_c = 3;
std::cout << _namename_WhatAFuckDay << _namename_ << _name_c << std::endl;

//2.函数指针场景

#define COMMAND(NAME) { #NAME, NAME ## _command }

// ** user code ** //
struct command {
	char *name;

        using function = void(*)(void);
        function pFunc;
};

struct command commands[] = {
	COMMAND (quit),
	COMMAND (help),
	...
};

// ** 编译时 ** //
struct command commands[] = {
	{ "quit", quit_command },
	{ "help", help_command },
	...
};