Sta facendo uso di C digraphs che erano modifiche allo standard C nel 1994 e quindi parte dello standard C99. Scambiare i digrammi con i loro caratteri effettivi, si ottiene:
#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);
}
Quindi, tenere a mente che a##b
si fonderanno insieme l'ingresso in un unico identificatore. Dal momento che la macro è appena passato a
e b
, il risultato è appena ab
, in modo da avere in modo efficace:
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);
}
L'assegnazione di c
non è davvero rilevante, in modo che può sbarazzarsi di che:
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);
}
Ora, cerchiamo di sbarazzarsi del operatore ternario (?:
), perché siamo in grado di lavorare fuori in modo statico (ab[a]
è sempre vero, perché è a
1 e ab[1]
è 20, vale a dire non-zero):
0.123.516,410617 millions
main()
{
int a=1, b=2, ab[]={10,20};
printf("%d", ab[a]);
printf("%d", a);
printf("%d", a);
}
Ora, sostituire le variabili con i loro valori attuali, vale a dire con ab[a]
20
e a
con 1
main()
{
int a=1, b=2, ab[]={10,20};
printf("%d", 20);
printf("%d", 1);
printf("%d", 1);
}
Eventuali duplicati di [cosa il C ??! ??! operatore do?] (http://stackoverflow.com/questions/7825055/what-does-the-c-operator-do) – GSerg
È questo dal contest C offuscato? –
non può spiegare, anche non ho visto prima. Compila in osx/darwin/unix. Per prima cosa, la prima riga valuta e stampa '20', seconda riga' 1', terza riga '1'. – user3078414