我找到了这个C代码示例,我非常困惑:
#include <stdio.h>
#define M(a,b) a%:%:b
main()
{
int a=1, b=2, ab[]={10,20}, c;
printf( "%d", M(a,b)<:a:> );
printf( "%d", M(a,b)<:a:>?a:b );
printf( "%d", c=M(a,b)<:a:>?a:b );
}
有人可以解释这应该做什么吗?它甚至不能在Visual Studio中编译,但我在线运行(在ideone.com上)并打印2011
,这也增加了混乱。
答案 0 :(得分:38)
它利用了C digraphs,这是1994年对C标准的修订,因此也是C99标准的一部分。将digraphs与他们的实际角色交换出来,你得到:
#include <stdio.h>
#define M(a,b) a##b
main()
{
int a=1, b=2, ab[]={10,20}, c;
printf( "%d", M(a,b)[a] );
printf( "%d", M(a,b)[a]?a:b );
printf( "%d", c=M(a,b)[a]?a:b );
}
因此,请记住,a##b
会将输入合并到一个标识符中。由于宏刚刚传递a
和b
,结果只有ab
,因此您实际上有:
main()
{
int a=1, b=2, ab[]={10,20}, c;
printf( "%d", ab[a] );
printf( "%d", ab[a]?a:b );
printf( "%d", c=ab[a]?a:b );
}
c
的分配并不真正相关,所以我们可以摆脱它:
main()
{
int a=1, b=2, ab[]={10,20};
printf( "%d", ab[a] );
printf( "%d", ab[a]?a:b );
printf( "%d", ab[a]?a:b );
}
现在,让我们摆脱三元运算符(?:
),因为我们可以静态地处理它(ab[a]
总是正确的,因为a
是1和{ {1}}为20,即非零):
ab[1]
现在,将变量替换为实际值,例如main()
{
int a=1, b=2, ab[]={10,20};
printf( "%d", ab[a] );
printf( "%d", a );
printf( "%d", a );
}
ab[a]
和20
a
1