Accueil
Rechercher:
sur developpez.com sur les forums
Forums | Tutoriels | F.A.Q's | Participez | Hébergement | Contacts
Club Emploi Blogs   TV   Dév. Web PHP XML Python Autres 2D-3D-Jeux Sécurité Windows Linux PC Mac
Accueil Conception Java DotNET Visual Basic  C  C++ Delphi MS-Office SQL & SGBD Oracle  4D  Business Intelligence
FORUMS C FAQs C TUTORIELS C LIVRES C COMPILATEURS C SOURCES GTK+
next up previous contents index
Next: Les entrées-sorties Up: Relations entre tableaux et Previous: Tableau et pointeur, c'est

Récréation

    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 up previous contents index
Next: Les entrées-sorties Up: Relations entre tableaux et Previous: Tableau et pointeur, c'est
Bernard Cassagne
1998-12-09
Responsable bénévole de la rubrique C : Arnaud Feltz (buchs) - Contacter par EMail :
Vos questions techniques : forum d'entraide C - Publiez vos articles, tutoriels et cours
et rejoignez-nous dans l'équipe de rédaction du club d'entraide des développeurs francophones
Nous contacter - Copyright © 2000-2008 www.developpez.com - Legal informations.