What is a##b
& #a
?
什么是## #b #a?
#define f(a,b) a##b
#define g(a) #a
#define h(a) g(a)
main()
{
printf("%s\n",h(f(1,2))); //how should I interpret this?? [line 1]
printf("%s\n",g(f(1,2))); //and this? [line 2]
}
How does this program work?
这个程序是如何工作的?
The output is
输出是
12
f(1, 2)
now I understand how a##b
& #a
work. But why is the result different in the two cases (line 1 and line 2)?
现在我明白了##b & #的工作。但是为什么两种情况下的结果不同(第1行和第2行)?
7 个解决方案
#1
19
The ## concatenates two tokens together. It can only be used in the preprocessor.
##将两个标记连接在一起。它只能在预处理器中使用。
f(1,2)
becomes 1 ## 2
becomes 12
.
f(1,2)变成1 # 2变成12。
The # operator by itself stringifies tokens: #a
becomes "a"
. Therefore, g(f(1,2))
becomes "f(1,2)"
when the preprocessor is done with it.
#操作符本身stringifies令牌:#a变成“a”。因此,当预处理程序完成时,g(f(1,2))变为“f(1,2)”。
h(f(1,2))
is effectively #(1 ## 2)
which becomes #12
which becomes "12"
as the preprocessor runs over it.
h(f(1,2))实际上是#(1 ## 2),它变成了#12,当预处理程序运行时,它变成了“12”。
#2
5
For questions like these (and also more "real-world" problems having to do with the preprocessor), I find it very helpful to actually read the code, after it has been preprocessed.
对于诸如此类的问题(以及与预处理器有关的更多“真实世界”问题),我发现在经过预处理之后,真正读懂代码是非常有用的。
How to do this varies with the compiler, but with gcc, you would use this:
如何做到这一点与编译器不同,但是对于gcc,您将使用以下方法:
$ gcc -E test.c
(snip)
main()
{
printf("%s\n","12");
printf("%s\n","f(1,2)");
}
So, you can see that the symbols have been both concatenated, and turned into a string.
你可以看到这些符号都被连接起来,变成了一个字符串。
#3
4
a##b will paste the code togather.
一个##b将把代码粘贴到一起。
so f(1,2) will become 12
所以f(1,2)变成12。
#4
3
The f(a,b) macro concatenates its arguments, g(a) turns its arguments to a string and h(a) is helper macro for g(a). I think it will output:
f(a,b)宏连接其参数,g(a)将其参数转换为字符串,h(a)为g(a)的辅助宏。我认为它会输出:
12
f(1,2)
The reason is that the h(a) macro causes its argument to be full expanded before passing it to g(a) while g(a) will take its arguments literally without expanding them first.
原因是h(a)宏在将其传递给g(a)之前,它的参数会被完整地扩展,而g(a)会在不首先扩展它们的情况下接受它的参数。
#5
0
a##b is the string contatenation of the literals a and b, so f(1,2) is "12"
a##b是文字a和b的字符串contatenation,所以f(1,2)是"12"
#a is the string literal a, so g(3) is "3"
#a是字符串文字a,所以g(3)是"3"
#6
0
## is the macro concatenation operator. So for example f(foo,bar)
would be equivalent to foobar
.
#是宏连接操作符。例如f(foo,bar)等于foobar。
#7
0
#define f(a,b) a##b #define g(a) #a #define h(a) g(a)
So, ## combine 2 parts directly together, no matter what types they are... Give you a example.. printf("%d\n",f(1,2));
you get 12, that means here f(1,2) is 12 a integer.
所以,##将两个部分直接合并在一起,不管它们是什么类型…给你一个例子。printf(" % d \ n”,f(1、2);得到12,这意味着f(1,2)是12个整数。
int a2 = 100; printf("%d\n",f(a,2));
here f(a,2) is label. it points to a label in your code context, if there is not int a2 = 100
, you get compile errors. And #a
turns whatever a is , into a string... And then h(a) g(a)
It's very strange.. It looks that when you call h(a), it turns to g(a), and passes a into g(a), firstly, it interprets what a is. so, before you can g(a), a is transformed to f(a,b) = a##b = 12
这里f(2)标签。它指向代码上下文中的一个标签,如果没有int a2 = 100,就会出现编译错误。而#a把a变成了一个字符串…然后h(a) g(a)很奇怪当你调用h(a)时,它会变成g(a),然后将a传递给g(a),首先,它解释a是什么。因此,在g(a)之前,a被转化为f(a,b) = a# b = 12。
#1
19
The ## concatenates two tokens together. It can only be used in the preprocessor.
##将两个标记连接在一起。它只能在预处理器中使用。
f(1,2)
becomes 1 ## 2
becomes 12
.
f(1,2)变成1 # 2变成12。
The # operator by itself stringifies tokens: #a
becomes "a"
. Therefore, g(f(1,2))
becomes "f(1,2)"
when the preprocessor is done with it.
#操作符本身stringifies令牌:#a变成“a”。因此,当预处理程序完成时,g(f(1,2))变为“f(1,2)”。
h(f(1,2))
is effectively #(1 ## 2)
which becomes #12
which becomes "12"
as the preprocessor runs over it.
h(f(1,2))实际上是#(1 ## 2),它变成了#12,当预处理程序运行时,它变成了“12”。
#2
5
For questions like these (and also more "real-world" problems having to do with the preprocessor), I find it very helpful to actually read the code, after it has been preprocessed.
对于诸如此类的问题(以及与预处理器有关的更多“真实世界”问题),我发现在经过预处理之后,真正读懂代码是非常有用的。
How to do this varies with the compiler, but with gcc, you would use this:
如何做到这一点与编译器不同,但是对于gcc,您将使用以下方法:
$ gcc -E test.c
(snip)
main()
{
printf("%s\n","12");
printf("%s\n","f(1,2)");
}
So, you can see that the symbols have been both concatenated, and turned into a string.
你可以看到这些符号都被连接起来,变成了一个字符串。
#3
4
a##b will paste the code togather.
一个##b将把代码粘贴到一起。
so f(1,2) will become 12
所以f(1,2)变成12。
#4
3
The f(a,b) macro concatenates its arguments, g(a) turns its arguments to a string and h(a) is helper macro for g(a). I think it will output:
f(a,b)宏连接其参数,g(a)将其参数转换为字符串,h(a)为g(a)的辅助宏。我认为它会输出:
12
f(1,2)
The reason is that the h(a) macro causes its argument to be full expanded before passing it to g(a) while g(a) will take its arguments literally without expanding them first.
原因是h(a)宏在将其传递给g(a)之前,它的参数会被完整地扩展,而g(a)会在不首先扩展它们的情况下接受它的参数。
#5
0
a##b is the string contatenation of the literals a and b, so f(1,2) is "12"
a##b是文字a和b的字符串contatenation,所以f(1,2)是"12"
#a is the string literal a, so g(3) is "3"
#a是字符串文字a,所以g(3)是"3"
#6
0
## is the macro concatenation operator. So for example f(foo,bar)
would be equivalent to foobar
.
#是宏连接操作符。例如f(foo,bar)等于foobar。
#7
0
#define f(a,b) a##b #define g(a) #a #define h(a) g(a)
So, ## combine 2 parts directly together, no matter what types they are... Give you a example.. printf("%d\n",f(1,2));
you get 12, that means here f(1,2) is 12 a integer.
所以,##将两个部分直接合并在一起,不管它们是什么类型…给你一个例子。printf(" % d \ n”,f(1、2);得到12,这意味着f(1,2)是12个整数。
int a2 = 100; printf("%d\n",f(a,2));
here f(a,2) is label. it points to a label in your code context, if there is not int a2 = 100
, you get compile errors. And #a
turns whatever a is , into a string... And then h(a) g(a)
It's very strange.. It looks that when you call h(a), it turns to g(a), and passes a into g(a), firstly, it interprets what a is. so, before you can g(a), a is transformed to f(a,b) = a##b = 12
这里f(2)标签。它指向代码上下文中的一个标签,如果没有int a2 = 100,就会出现编译错误。而#a把a变成了一个字符串…然后h(a) g(a)很奇怪当你调用h(a)时,它会变成g(a),然后将a传递给g(a),首先,它解释a是什么。因此,在g(a)之前,a被转化为f(a,b) = a# b = 12。