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竞赛吗?
- 无法解释,也从未见过。它在osx/darwin/unix中编译。仅供参考,第一行评估并打印20、第二行1、第三行1。
- 为什么可以int$[:>=<%-!0,};编译?
- @这些是有向图,不是三向图。虽然他们有关系,但我认为这不是一个骗局。
- @Dreamlax有向图也被提到了,所以我认为它可以。
- 有向图每天都会被问到关于stackoverflow的字面意思。我不明白为什么有那么多同一个问题的副本会出现在热门问题列表中…或者为什么它们不作为复制品关闭。"—Blueraja-Danny Pflughoeft,8月14日15:16:27
- @GSERG的问题有很多不同的混淆,合并成一个goo,这对于复制来说是相当糟糕的。更确切地说,把那个作为这个的复制品关闭。
它使用了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将把输入合并到一个标识符中。由于宏刚刚通过a和b,所以结果只是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]替换为20,a替换为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 );
} |
- 令人印象深刻的分析
- 哇,这打开了一个全新的可能性世界。D:谢谢!
- @安乐死:不,不,不,假装你从未见过。
- @安乐死有向图和三向图是一些非常糟糕的想法,这些想法被添加到标准中,以支持世界各地各种不同的计算机键盘布局(而不是提出一个关键字标准)。他们是过去的事,现在他们被视为100%的坏做法。
- 现在他们应该为emoji添加类似的支持吗??