Он использует C digraphs, которые были поправками к стандарту C в 1994 году и, следовательно, частью стандарта 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);
}
Итак, имейте в виду, что 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 и ab[1]
составляет 20, то есть ненулевая):
main()
{
int a=1, b=2, ab[]={10,20};
printf("%d", ab[a]);
printf("%d", a);
printf("%d", a);
}
Теперь замените переменные с их фактическими значениями, т.е. ab[a]
с 20
и a
с 1
main()
{
int a=1, b=2, ab[]={10,20};
printf("%d", 20);
printf("%d", 1);
printf("%d", 1);
}
Возможный дубликат [Что делает C ??! ??! оператор делает?] (http://stackoverflow.com/questions/7825055/what-does-the-c-operator-do) – GSerg
Это из обфускации C-конкурса? –
не могу объяснить, также не видел раньше. Он компилируется в osx/darwin/unix. FYI, первая строка оценивает и печатает '20', вторую строку' 1', третью строку '1'. – user3078414