C奇怪的宏语法

C strange macro syntax

我找到了这个C代码示例,我完全困惑了:

1
2
3
4
5
6
7
8
9
10
#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,这也增加了混乱。


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

1
2
3
4
5
6
7
8
9
10
#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将把输入合并到一个标识符中。由于宏刚刚通过ab,所以结果只是ab,所以您实际上有:

1
2
3
4
5
6
7
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的任务并不真正相关,因此我们可以取消:

1
2
3
4
5
6
7
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,即非零):

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

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

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