宏定义中出现两个#是怎么个用法

rabbitjerry 2012-09-11 10:24:37
一个C文档中的一个宏定义比较复杂,如下。其中多处出现##。这个是什么意思啊?


#define _COMPARE_TEMPLATE(MXC) \
Pair* compare_##MXC (Pair* pairs_iterator, \
const TYPEOF_##MXC * L1_pt, \
const TYPEOF_##MXC * L2_pt, \
int K1, int K2, int ND, float thresh) \
{ \
int k1, k2 ; \
const PROMOTE_##MXC maxval = MAXVAL_##MXC ; \
for(k1 = 0 ; k1 < K1 ; ++k1, L1_pt += ND ) { \
\
PROMOTE_##MXC best = maxval ; \
PROMOTE_##MXC second_best = maxval ; \
int bestk = -1 ; \
\
/* For each point P2[k2] in the second image... */ \
for(k2 = 0 ; k2 < K2 ; ++k2, L2_pt += ND) { \
\
int bin ; \
PROMOTE_##MXC acc = 0 ; \
for(bin = 0 ; bin < ND ; ++bin) { \
PROMOTE_##MXC delta = \
((PROMOTE_##MXC) L1_pt[bin]) - \
((PROMOTE_##MXC) L2_pt[bin]) ; \
acc += delta*delta ; \
} \
\
/* Filter the best and second best matching point. */ \
if(acc < best) { \
second_best = best ; \
best = acc ; \
bestk = k2 ; \
} else if(acc < second_best) { \
second_best = acc ; \
} \
} \
\
L2_pt -= ND*K2 ; \
\
/* Lowe's method: accept the match only if unique. */ \
if(thresh * (float) best <= (float) second_best && \
bestk != -1) { \
pairs_iterator->k1 = k1 ; \
pairs_iterator->k2 = bestk ; \
pairs_iterator->score = best ; \
pairs_iterator++ ; \
} \
} \
\
return pairs_iterator ; \
} \

_COMPARE_TEMPLATE( mxDOUBLE_CLASS )
_COMPARE_TEMPLATE( mxSINGLE_CLASS )
_COMPARE_TEMPLATE( mxINT8_CLASS )
_COMPARE_TEMPLATE( mxUINT8_CLASS )
...全文
617 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
qqqaxiye 2013-08-11
  • 打赏
  • 举报
回复
你好,偶然发现楼主之前也在看这个程序,有几个问题能否请教楼主呢?
Corner 2012-09-11
  • 打赏
  • 举报
回复
#的功能是将其后面的宏参数进行字符串化操作
##用来将多个Token连接为一个Token
pathuang68 2012-09-11
  • 打赏
  • 举报
回复
参考:

#include <iostream>
using namespace std;

#define X "abc"##"def" // 将abc和def连起来

int main(void)
{
cout << X << endl; // 输出abcdef

return 0;
}
wizard_tiger 2012-09-11
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]

#与##在宏定义中的--宏展开
#include <stdio.h>
#define f(a,b) a##b
#define g(a) #a
#define h(a) g(a)
int main()
{
printf("%s\n", h(f(1,2))); // 12
printf("%s\n", g(f(1,2))); // f(1,2)……
[/Quote]
学习,学习!
Gloveing 2012-09-11
  • 打赏
  • 举报
回复
Token-Pasting Operator (##)
The double-number-sign or “token-pasting” operator (##), which is sometimes called the “merging” operator, is used in both object-like and function-like macros. It permits separate tokens to be joined into a single token and therefore cannot be the first or last token in the macro definition.

If a formal parameter in a macro definition is preceded or followed by the token-pasting operator, the formal parameter is immediately replaced by the unexpanded actual argument. Macro expansion is not performed on the argument prior to replacement.

Then, each occurrence of the token-pasting operator in token-string is removed, and the tokens preceding and following it are concatenated. The resulting token must be a valid token. If it is, the token is scanned for possible replacement if it represents a macro name. The identifier represents the name by which the concatenated tokens will be known in the program before replacement. Each token represents a token defined elsewhere, either within the program or on the compiler command line. White space preceding or following the operator is optional.

This example illustrates use of both the stringizing and token-pasting operators in specifying program output:

#define paster( n ) printf( "token" #n " = %d", token##n )
int token9 = 9;

If a macro is called with a numeric argument like

paster( 9 );

the macro yields

printf( "token" "9" " = %d", token9 );

which becomes

printf( "token9 = %d", token9 );

ARMBULL 2012-09-11
  • 打赏
  • 举报
回复
这个好玩...以前看过这个方式,现在总算明白原因了.哈哈
赵4老师 2012-09-11
  • 打赏
  • 举报
回复
#与##在宏定义中的--宏展开
#include <stdio.h>
#define f(a,b) a##b
#define g(a) #a
#define h(a) g(a)
int main()
{
printf("%s\n", h(f(1,2))); // 12
printf("%s\n", g(f(1,2))); // f(1,2)
return 0;
}
宏展开时:
如果宏定义以#开头,不展开参数,直接替换。
故g(f(1,2))--->#f(1,2)--->"f(1,2)";
如果宏定义不以#开头,展开参数,直接替换,由外层向里层,如果碰到的是#开头的宏,不继续往里层展开,往外层展开。
由外层向里层,如果碰到的是以非#开头的宏,继续往里层走,直至最里层,开始一层层往外层展开。
故h(f(1,2))--->h(12)--->g(12)---->#12----->"12"。
PS:
##在宏中定义,是字符连接符
如a##b##c 等同于 "abc"
#在宏开头出现,是表示宏展开的方式不同
#a 等同于"a"
#abc 等同于 "abc"
复杂的:
#include <stdio.h>
#define f(a,b) a##b
#define g(a) #a
#define h(a) g(a)
int main()
{
char a = 'a';
cout<<g(a)<<endl; // a
cout<<g(g(a))<<endl; // a
printf("%s\n", h(f(1,2))); // 12
printf("%s\n", g(f(1,2))); // f(1,2)
printf("%s\n", g(h(f(1,2)))); // h(f(1,2))
printf("%s\n", h(g(f(1,2)))); // "f(1,2)"
printf("%s\n", h(h(f(1,2)))); // "12"
system("pause");
return 0;
}
预处理后的:(在编译选项中添加/EP /P后编译生成的.i文件
int main()
{
char a = 'a';
cout<<"a"<<endl;
cout<<"g(a)"<<endl;
printf("%s\n", "12");
printf("%s\n", "f(1,2)");
printf("%s\n", "h(f(1,2))");
printf("%s\n", "\"f(1,2)\"");
printf("%s\n", "\"12\"");
system("pause");
return 0;
}
---------------------------------------------------
宏解析
1. ##操作符
##操作符它的作用是在替代表中将其前后的参数连接成为一个预处理符号,它不能出现于宏替代表的开端和末尾。
例:
#define concat(s,t) s##t
#define AAA ABC
concat(A, AA)
将被替换成
ABC
2. 重新扫描和替换
在替换列表中的所有参数替换过之后,预处理器将对结果token序列重新扫描以便对其中的宏再次替换。
当正在替换的宏在其替换列表中发现自身时,就不再对其进行替换。今儿,在任何正在嵌套替换的宏的替换过程中遇到正被替换的宏就对其不再进行替换(防止递归)。
例:
#define ROOT AAA CCC
#define AAA ROOT
ROOT
将被替换成
ROOT CCC

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧