Il utilise C digraphs qui étaient des amendements à la norme C en 1994 et qui font donc partie de la norme C99. Permutant les digraphs avec leurs personnages réels, vous obtenez:
#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);
}
Alors, gardez à l'esprit que a##b
va fusionner l'entrée en un seul identifiant. Étant donné que la macro est juste passé a
et b
, le résultat est juste ab
, de sorte que vous avez efficacement:
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'affectation à c
est pas vraiment pertinent, afin que nous puissions se débarrasser de cette:
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);
}
maintenant, se débarrasser de l'opérateur ternaire (?:
), parce que nous pouvons le travailler de manière statique (ab[a]
est toujours vrai parce que a
est 1 et ab[1]
est de 20, soit non nul):
main()
{
int a=1, b=2, ab[]={10,20};
printf("%d", ab[a]);
printf("%d", a);
printf("%d", a);
}
Maintenant, remplacez les variables par leurs valeurs réelles, à savoir ab[a]
avec 20
et a
avec 1
main()
{
int a=1, b=2, ab[]={10,20};
printf("%d", 20);
printf("%d", 1);
printf("%d", 1);
}
double possible de [Qu'est-ce que le C ??! ??! opérateur faire?] (http://stackoverflow.com/questions/7825055/what-does-the-c-operator-do) – GSerg
Est-ce que c'est un concours de C obscurci? –
ne peut pas expliquer, n'ont pas non plus vu auparavant. Il compile dans osx/darwin/unix. FYI, première ligne évalue et imprime «20», deuxième ligne «1», troisième ligne «1». – user3078414