C奇怪的宏语法

C奇怪的宏语法,c,macros,preprocessor-directive,C,Macros,Preprocessor Directive,我找到了这个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 ); } #包括 #定义M(a,b)a%

我找到了这个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 );
}
#包括
#定义M(a,b)a%:%:b
main()
{
inta=1,b=2,ab[]={10,20},c;
printf(“%d”,M(a,b));
printf(“%d”,M(a,b)?a:b;
printf(“%d”,c=M(a,b)?a:b;
}
有人能解释一下这是怎么回事吗?它甚至没有在Visual Studio中编译,但我在网上运行了它,它打印了
2011
,这也增加了混乱。

它所使用的是1994年对C标准的修订,因此是C99标准的一部分。将有向图与其实际字符交换,可以得到:

#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 );
}
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,
ab[1]
是20,即非零):

现在,将变量替换为实际值,即
ab[a]
替换为
20
a
替换为
1

main()
{
  int a=1, b=2, ab[]={10,20};
  printf( "%d", 20 );
  printf( "%d", 1 );
  printf( "%d", 1 );
}

这可能是来自模糊C竞赛的复制品吗?无法解释,也没有见过。它在osx/darwin/unix中编译。仅供参考,第一行计算并打印
20
,第二行
1
,第三行
1
@GSerg:这些是有向图而不是三向图。虽然它们是相关的,但我认为这并不是一个真正的重复。@GSerg问题与许多不同的混淆合并在一起,对于重复的问题是非常糟糕的。更确切地说,把它当作复制品来关闭。哇,这打开了一个充满可能性的全新世界D谢谢你@欧瑟比:不,不,不。假装你从未见过。@Eutherpy有向图和三向图是一些非常糟糕的想法,它们被添加到标准中,以支持世界各地各种奇特的计算机键盘布局(而不是提出关键字标准)。它们已经成为过去,现在它们被认为是100%的坏习惯。现在它们应该为表情符号添加类似的支持
main()
{
  int a=1, b=2, ab[]={10,20};
  printf( "%d", ab[a] );
  printf( "%d", a );
  printf( "%d", a );
}
main()
{
  int a=1, b=2, ab[]={10,20};
  printf( "%d", 20 );
  printf( "%d", 1 );
  printf( "%d", 1 );
}