Next: Les entrées-sorties
Up: Relations entre tableaux et
Previous: Tableau et pointeur, c'est
En illustration sur les bizarreries des tableaux dans le langage C,
voici la contribution de David Korn (le créateur du
korn shell) à la
compétition du code C le plus obscur (
IOCCC) de 1987 :
main() { printf(&unix["\021%six\012\0"],(unix)["have"]+"fun"-0x60);}
Non, ce programme n'imprime pas have fun with unix ou quelque chose de
ce genre !
Le lecteur est invité à essayer d'élucider ce programme (oui, il imprime
quelque chose, mais quoi ?)
la solution est donnée à la page suivante.
Voici les clés de la compréhension :
- 1.
- Tout compilateur C possède un certain nombre de constantes prédéfinies
dépendant de l'architecture de la machine sur laquelle il s'exécute.
En particulier, tout compilateur pour machine UNIX prédéfinit la
constante unix avec comme valeur 1.
Donc le programme est équivalent à :
main() { printf(&1["\021%six\012\0"],(1)["have"]+"fun"-0x60);}
- 2.
- Si on se souvient qu'on a vu en 4.2
que pour un tableau t,
t[i]
est équivalent à i[t], on voit que 1["\021%six\012\0"] est
équivalent à "\021%six\012\0"[1] et (1)["have"] à
"have"[1].
Donc &1["\021%six\012\0"] est l'adresse du caractère % dans la
chaîne "\021%six\012\0" et "have"[1] est le caractère 'a'.
On peut donc réécrire le programme :
main() { printf("%six\012\0", 'a' + "fun" -0x60);}
- 3.
- La fin d'une chaîne est signalée par un caractère null (
\0)
et le compilateur en met un à la fin de chaque chaîne littérale. Celui qui
est ici est donc inutile.
D'autre part, il existe une notation plus parlante pour le caractère de code
\012 (c'est à dire new line), il s'agit de la notation \n.
Le programme peut donc se réécrire :
main() { printf("%six\n", 'a' + "fun" -0x60);}
- 4.
- Le caractère
'a' a pour code ASCII 0x61, donc
'a' -0x60 est égal à 1.
Réécrivons le programme :
main() { printf("%six\n","fun" + 1); }
- 5.
"fun" + 1 est l'adresse du caractère u dans la chaîne "fun",
le programme devient donc :
main() { printf("%six\n","un"); }
il imprime donc unix.
Next: Les entrées-sorties
Up: Relations entre tableaux et
Previous: Tableau et pointeur, c'est
Bernard Cassagne
1998-12-09