You are on page 1of 29

1. 2.

2.1. 2.2. 2.3.

POSITION DU PROBLEME LES CONTRAINTES AVEC LESQUELLES IL FAUT COMPOSER


La dure ralit Laccs au mot Ladressage

2 2
2 2 2

3.
3.1. 3.2. 3.3.

LES TYPES SCALAIRES


Les entiers Les nombres rels Les caractres

4
4 10 13

4.
4.1. 4.2. 4.3.

LES TYPES STRUCTURES


Les tableaux (& chanes de caractres) Les enregistrements Les variants

19
19 21 23

5.
5.1. 5.2.

LES POINTEURS
Quest-ce que cest ? Que se passe-t-il lors dun malloc et dun free ?

26
26 26

6.

TABLE DES ILLUSTRATIONS

29

1 / 29

1. Position du problme
La question que se pose linformaticien (ou le concepteur de machine) est de reprsenter informatiquement des concepts plus ou moins abstraits (mathmatiques par exemple) en tant oblig de prendre en compte la performance (temps, place) dont le facteur essentiel est en gnral la question du repliement sur les mots machines (32, 64 bits,et certains se souviennent des 16, 8 et 4 bits). Certains choix de reprsentation pour les types scalaires (ceux dont le programmeur ne veut pas savoir la structure) sont classiques, voire obissent des standards et sont tellement habituels que souvent les programmeurs les ignorent compltement, jusqu tomber dans les failles de la reprsentation et subir des erreurs mystrieuses. Les choix de reprsentation pour les types structurs sont au contraire des types scalaires la discrtion de limplmenteur du compilateur (il ny a pas ou peu de standards dans le domaine). Nanmoins il y a un tat de lart qui fait que lon peut documenter les solutions les plus classiques. Certains choix sont laisss la discrtion du programmeur, en particulier pour ce qui est des types structurs quand cest lui qui dfinit le type de donnes mais pas seulement (voir en Ada, Clauses de reprsentation 4.2.1 p21).

2. Les contraintes avec lesquelles il faut composer


2.1. La dure ralit

Linformatique nest pas une option de lcole de Poudlard : ce qui est impossible sur le papier est aussi impossible en informatique, par exemple on verra en 3.2 que lon ne peut pas plus reprsenter dans une machine la valeur dun nombre rel dans le cas gnral quon ne peut le faire sur le papier, et en 3.1 que ce qui est infini sur le papier (la longueur maximum dun entier) ne tient pas dans une machine non plus.
Figure 1 Linformatique nest pas de la sorcellerie

2.2.

Laccs au mot

Les machines ne travaillent efficacement que par mots , dailleurs larchitecture des processeurs est compltement oriente pour tre efficace lorsque les donnes sont des multiples de x bits (x=16, 32,) pour des raisons videntes (penser la propagation de retenues en arithmtique, par exemple), le meilleur facteur multiplicatif tant videmment 1.

2.3.

Ladressage

Il est assez frquent que lon veuille travailler avec ladresse dune donne (oprateur & en C) pour faire des structures dynamiques ou passer des objets par rfrence. Le problme ici est

2 / 29

que tout na pas une adresse en mmoire : par exemple en C, le langage ne permet pas dadresser les bits individuellement (cest loctet, le char, latome adressable). De surcrot le langage masque ici le fait que souvent la machine doit aller chercher 32 bits pour rcuprer loctet que le programmeur a limpression dadresser individuellement1. Notons en passant que C ne permet pas non plus de demander ladresse dune variable dclare register , et pour cause, elle na pas dadresse. Evidemment tout ceci est une gnralit et certains processeurs, dans certaines configurations, peuvent faire des choses plus fines. Mais ds que cest programm en C, la facilit disparat de toutes faons.

Par exemple, si on crit : char * s = malloc(10) ; S[2]=A ; eh bien probablement la machine ira chercher S[0..3] pour crire dans S[2] et ensuite rcrire dans S[0..3].

3 / 29

3. Les types scalaires


3.1. Les entiers
Il sagit de reprsenter le concept mathmatique dentier, qui se dfinit abstraitement de diffrentes faons (Peano : 0 est un entier naturel, tout entier naturel a un successeur, aucun entier naturel n'a 0 pour successeur. deux entiers naturels ayant mme successeur sont gaux et est lensemble qui contient 0 et le successeur de chacun de ses lments.) Le problme ici est linfinit qui se replie mal (euphmisme) sur des machines 32 ou 64 bits. Si donc on dcide quil est indispensable de pouvoir reprsenter nimporte quel entier, la solution sera lourde et finira en tableau de taille variable, ce qui peut avoir son intrt, voir paragraphe 3.2.2. Si au contraire on pense quun nombre raisonnable de reprsentations suffira au bonheur de limplmentation, on arrive fatalement reprsenter un intervalle ce qui va engendrer une varit de soucis et autant de types (en C : char, short, int, long) avec les questions de conversion. L o le mathmaticien connat un entier abstrait, linformaticien doit en gnral faire avec des entiers qui sont en fait des intervalles de lentier mathmatique.

3.1.1. Entiers non signs


La solution nave et la plus utilise consiste utiliser, comme reprsentation dun intervalle dentiers, la numrotation dite base 2 : 000 001 010 011 100 etc. Il faut bien tre conscient que ce nest quune convention, en particulier la dcision de quel bit reprsente quelle puissance de deux est compltement arbitraire. Le bit de poids fort peut tre une extrmit, lautre ouau nimporte o, car entre bits dun mme octet il ny a videmment ni gauche ni droite ni adresse haute ou basse : seul loctet est en gnral adressable. La seule implication est la logique de lunit arithmtique du processeur qui doit tre cohrente avec le choix fait. Le programmeur ny peut rien, cest un choix matriel. Une fois les bits arrangs, ils seront toujours reprsents poids fort gauche , reste la question du sens quon donne aux successions doctets. Sur 16 bits, va-t-on reprsenter 1 comme ci : (00000000)(00000001) ou comme a : (00000001)(00000000). Le problme est parfois dit : problme IXUN (avec ses variantes NUXI et XINU) selon lordre dans lesquelles les lettres de UNIX , chacune code sur un octet, sont retrouves aprs passage sur une machine qui a fait un autre choix. Vocabulaire : quand loctet de poids fort est gauche, on dit que la machine est big endian (68000, Sparc) . droite, ce sera little endian (Pentium). Big/little visent la force de loctet qui a ladresse la plus basse2. Parfois les machines sont dites middle-endian quand elles utilisent les deux formes par exemple selon la taille des donnes. Ceci na rien voir avec les indiens, mme si le jeu de mots est l.
Figure 2 Little Indian et Big Indian
2

Testez votre machine: int x=1 ; si * ((char*) (&i)) vaut 1, la machine est little endian (on lit loctet le plus gauche de lentier).

4 / 29

Little Endian/Big Endian Ces termes furent dfinis par un beau premier Avril de 1980 (noter la date) par Dany Cohen, dans un article rest clbre o il tentait de mettre fin une (stupide) controverse entre les partisans des deux solutions ; la big est plus aise dboguer car on lit de gauche droite, la little met ladresse forte loctet de poids fort et daucuns trouvent a plus logique sil faut transmettre les octets dans un ordre donn.
ON HOLY WARS AND A PLEA FOR PEACE INTRODUCTION This is an attempt to stop a war. I hope it is not too late and that somehow, magically perhaps, peace will prevail again. The latecomers into the arena believe that the issue is: proper byte order in messages?". "What is the

The root of the conflict lies much deeper than that. It is the question of which bit should travel first, the bit from the little end of the word, or the bit from the big end of the word? The followers of the former approach are called the Little-Endians, and the followers of the latter are called the Big-Endians. The details of the holy war between the Little-Endians and the Big-Endians are documented in [6] and described, in brief, in the Appendix. I recommend that you read it at this point.

Figure 3 Gulliver Lilliput

Les notes et appendices expliquent que les termes viennent des Voyages de Gulliver o, dans le monde de Lilliput, une guerre fait rage entre ceux qui ouvrent leurs ufs par le gros bout (Big-Endians) et ceux qui louvrent par le petit bout (Little-Endians). Le jeu de mots est vident pour un anglophone, moins pour un francophone qui a lu Swift avec la traduction petit-boutien/gros-boutien .

3.1.2. Entiers signs


La question de la reprsentation du signe est tout sauf triviale. On peut prendre lapproche nave qui consiste sparer le signe de la valeur absolue, exactement ce quon fait couramment en base 10 dans la vie courante : on crit +5 et -5. Cela conduit concrtement ddier un bit linformation de signe, disons celui de gauche et pour des raisons obscures cette notation sappelle complment un 3. Mais hlas cela conduit aussi un trs gros inconvnient : il y a deux zros (+0 et-0) ce qui complique les tests dgalit dans lunit
3

En fait la raison nest pas si obscure, cest simplement que lopration consiste inverser tous les bits de X pour obtenir X. Un seul bit suffirait le signe- mais ce serait la limite moins performant. Et complmenter un est une faon complique de dire inverser quand il ny a quun bit.

5 / 29

arithmtique le test dgalit est simple si la comparaison des bits suffit, sans avoir chercher la signification quils ont. Il y a aussi un inconvnient, moindre : puisquil y a deux zros, on perd une position de codage, on ne peut coder que de (2N-1) +(2 N-1). Mais le vrai souci est dans la gestion de larithmtique : chacun se souvient des durs moments o, lcole, il a fallu apprendre que la soustraction entre deux entiers relatifs de mme signe impose que lon soustraie les valeurs absolues (grande moins petite) et que lon donne au rsultat le signe du plus grand en valeur absolue. Alors que si les signes sont diffrents, etc, etcToutes oprations qui sont de vraies catastrophes quand il faut les implmenter en termes de logique lectronique : tests, troncatures, cas particuliers. Idem pour laddition, qui devient une soustraction quand les signes sont diffrents. La solution quasi universellement retenue est dutiliser la notation dite complment deux . Ici le bit de gauche est aussi le bit de signe, mais les autres ne reprsentent pas la valeur absolue.
Figure 4 Embarras causs par laddition de deux entiers relatifs

Exemple sur quatre bits :

7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5 -6 -7 -8

0111 0110 0101 0100 0011 0010 0001 0000 1111 1110 1101 1100 1011 1010 1001 1000

On peut noter plusieurs choses: Il nest pas immdiat de complmenter : pour obtenir X partir de X, la rgle est 1/ complmenter tous les bits et 2/ajouter 1 en interprtant le mot comme un entier non sign et en oubliant la retenue finale sil y en a.4 Il ny a quun zro. Le bit de gauche est le signe (1 = moins). La plage de valeurs reprsentables va de 2(N-1) +2(N-1) -1 (on en gagne une !) On peut considrer que cest un grand dcalage des nombres naturels : en soustrayant chacun une constante gale la moiti de ltendue du type et en ignorant la dernire retenue. Lavantage apparat ds que lon veut faire des oprations : laddition et la soustraction ne demandent plus grer des cas particuliers ni des questions de valeur absolue. Exemple : 3 + (-5) : on pose lopration et on additionne bit bit sans se soucier dune ventuelle retenue finale ni des signes des arguments: 3 -5
Retenue

0011 1011
011

-2
4

1110

Et cest pour cela que a sappelle complment deux : on a complment un, et ajout un.

6 / 29

Notons titre anecdotique que la mme mthode pourrait tre utilise en base 10, et que si on ne le fait pas cest par conomie de place (on ncrit pas les nombres sur un nombre de chiffres constant, et on a plus vite crit il fait -2 degrs que il fait 9998 degrs ). Mais si lon samusait reprsenter les entiers relatifs de la faon suivante (voir droite) et quon dcide que le 0 ou 9 gauche est lindicateur de signe, on retrouve la mme bonne proprit de ne plus avoir de cas particuliers : 3 -5
Retenue

0003 9995
000

5 4 3 2 1 0 -1 -2 -3 -4 -5

0005 0004 0003 0002 0001 0000 9999 9998 9997 9996 9995

-2

9998

3.1.3. Cas despce

3.1.3.1. Virgule fixe


Les nombres flottants prcision absolue, utiliss par exemple dans les applications comptables : le budget de lEtat et celui de Madame Michu ont tous deux besoin de calculer les centimes, la diffrence entre les deux est lie la taille de la reprsentation. On remarque tout de suite que ceci entre facilement dans le cas de figure de la reprsentation entire : il suffit de dcaler la virgule du nombre de digits ncessaires pour retomber dans le cas de figure type discret. Ce qui revient, dans le cas du budget, calculer en centimes pour rester en nombres entiers.

3.1.3.2. Codages divers


Le fait que lon code un intervalle dentiers par la squence binaire 000,001,010,011 nimplique pas forcment que 000 reprsente zro, 001 un, etc.

7 / 29

Code de Gray
Cest un paradigme de codage ad-hoc o la proprit que lon espre est le fait que dun entier lautre, le codage ne change que dun bit. Ce code est trs utilis dans les systmes de capture de donnes lectromcaniques (roues codeuses par exemple) ou dans les codages dtat des machines FSM. Dans de tels dispositifs, on peut admettre que la transition entre deux tats rende de faon incertaine la valeur de lun ou la valeur de lautre, mais pas une valeur incohrente, ce qui serait le cas en codage normal si, en passant de 0111 (7) 1000 (8) on avait un tat transitoire 1111 (15) ou 0000 d des alas mcaniques ou capacitifs. Code de Gray (on notera la priodicid verticale des motifs de 0 et 1): 0 000 1 001 2 011 3 010 4 110 5 111 6 101 7 100
Figure 5 - Roue codeuse

Intervalles ne commenant pas zro


Rien ne dit que tous les types entiers manipuls ont forcment besoin dune tendue allant de zro une borne max. Par exemple, la reprsentation de la temprature dune population hospitalise (vivante, on fera limpasse sur le dpositoire et sur lincinration) aura, avec une bonne marge une tendue de lordre 35-42. Il est donc tout fait lgitime doptimiser la place occupe et de coder 35 avec 000, 36 avec 001, etc. et trois bits seront suffisants l o il en aurait fallu six si lon avait commenc zro. Noter que dans ce cas, larithmtique doit tre gre par le compilateur, chaque opration devant faire lobjet dune correction le cas chant. On peut mme imaginer des intervalles dentiers discontinus ainsi reprsents par une squence continue . La seule chose qui compte in fine, cest quil y ait bijection entre les valeurs pertinentes et la squence de combinaisons de bits utilise, et que les oprations correspondantes soient translates proprement par le compilateur.

3.1.3.3. Conversions
Dans beaucoup de langages (en C par exemple) se pose la question de grer simultanment plusieurs types entiers (de taille voire dintervalles diffrents). Or si lutilisateur sait bien que 115, cest 115 et quoi en faire, cest un vrai souci pour le compilateur que de grer le 115 cod sur un char (un octet) en mme temps que celui cod sur un int (32 bits).
01110011 => 00000000 00000000 00000000 01110011

On comprend bien sur cet exemple simple le choix de C (la conversion est automatique dans le sens petit=>grand) car il suffit de rajouter des zros gauche. Mais les choses se gtent quand le nombre est ngatif : -115 va tre cod avec un 1 sur le bit numro 8 (cas du char) et la conversion en int suppose au contraire de rajouter des 1 gauche.
10001101 => 11111111 1111111 11111111 10001101

8 / 29

L-dessus, des langages comme Pascal, Ada ou VHDL permettent de spcifier des bornes aux types entiers (borne basse et borne haute) et non pas seulement une tendue comme en C (de 0 N-1). Du coup, notre 115 peut trs bien tre reprsent par 010 si le type auquel il appartient est spcifi comme allant de 113 120, et toute conversion devient coteuse (ne peut plus se ramener des bourrages de 0 ou de 1 gauche). Cest pourquoi dailleurs Ada et VHDL, tout en autorisant toutes les conversions entre types numriques, obligent ce quelles soient explicites de faon que lon voie bien quil y a un cot. En C, cerise sur le gteau, les types enum peuvent tre compils dans le type le plus petit capable de reprsenter toutes les valeurs . Cest ainsi quun objet de ce type peut brusquement passer de char short au hasard dune valeur ajoute ou enleve dans un enum. Cest en gnral transparent maispas toujours. Et cest pourquoi souvent les programmeurs ajoutent une valeur bidon dans leur enum :
typedef enum {bleu, blanc, rouge, bidon=66000} toto ;

Ceci va forcer le compilateur utiliser un type capable de reprsenter 66000, c'est--dire int. Sinon, aurait pu tre un char ou un short selon le nombre des autres valeurs.

9 / 29

3.2.

Les nombres rels

La reprsentation des nombres rels est un vritable casse-tte ; en effet, si lon soblige coller aux mots-machine, le problme est insoluble : il ny a quun nombre fini de combinaisons alors que la premire proprit des rels est de ntre pas discrets (entre deux rels on peut toujours en trouver un troisime). On peut toujours, comme signal plus haut, faire une croix sur la performance si lon veut une reprsentation exacte et utiliser une reprsentation base de tableaux de taille variable et dindicateurs tels que racine ou PI ; ce qui revient, dune faon ou dune autre, ne pas reprsenter le rel mais la faon de le calculer. Si nanmoins on veut tenter le coup, on va dcider de reprsenter seulement certains nombres rels dans une tendue que lon fixera par avance. Et les autres ? Eh bien tant pis pour eux, ou plus exactement tant pis pour celui qui simagine avoir affaire dhonntes rels. Si un calcul tombe ct des nombres reprsents (cas gnral), il sera arrondi. Il y a plein de mauvaises consquences que lon peut mettre en vidence facilement : certaines oprations ne sont pas commutative, par exemple, alors quelles devraient ltre. Mais surtout, cela implique que les oprateurs de comparaison sont incertains, surtout lgalit et la diffrence. Une comparaison par == de deux nombres rels dans un test est toujours suspecte !

3.2.1. Le standard IEEE


Dune faon gnrale, on va utiliser une reprsentation canonique et normalise. Canonique pour pouvoir facilement comparer les objets sans avoir besoin de la signification de chaque bit. Normalise parce que sil existe des standards, ils seront cbls en dur dans les processeurs do efficacit dans un domaine o elle nest pas de trop. Lide est donc de sparer les rels en trois champs : le signe, la mantisse et lexposant. Le problme du double zro (plus zro et moins zro) se posera donc et devra tre rgl. La mantisse et lexposant (exprims videmment en base 2) seront canoniss comme suit : on rglera lexposant de sorte que la mantisse soit comprise en binaire !- entre 1 (compris) et 10 (non compris). Une fois ceci assur, il est clair que tous les nombres seront sous la forme +/- 1,xyzt * 2ee et donc seuls le signe, xyzt et ee ont besoin dtre reprsents (autrement dit, la mantisse commence toujours par 1, et il est inutile de coder a.
Figure 6 - Le Savant Cosinus dans l'histoire du Pont Neuf

10 / 29

La norme la plus utilise est base sur le IEEE754. Qui se dcline en 1/23/8 bits pour le signe/exposant/mantisse (simple prcision, capable daller jusqu 1038) et 1/52/11 (double prcision, jusqu 10308). Le signe : 1 bit Lexposant : 8 ou 11 bits (on ajoute 127 ou 1023 lexposant pour ne pas avoir grer en sus des entiers signs.) La mantisse : 23 ou 52 bits. Indpendamment des valeurs plus grandes ou plus petites que les extrmes, on remarque que zro nest pas reprsentable avec cette notation (la mantisse est suppose commencer toujours par 1, !..). On dcide donc, en sacrifiant lexposant 000 (signifiant -127 en simple prcision) que tous les bits zro signifie zro. Si lexposant est zro (-127 on est donc dans les tout petits nombres) mais pas la mantisse, alors par une autre exception on entre dans les nombres dnormaliss pour lesquels on ne fait plus la fameuse hypothse du 1, , ce qui permet de descendre jusqu 2-149 pour ce qui est des nombres reprsents (en simple prcision). En sacrifiant une autre valeur dexposant la gnralit (tous les bits de lexposant 1) on va pouvoir reprsenter linfini (mantisse zro) et le clbre par ses messages derreur- NaN (mantisse pas zro). NaN signifie Not a Number . En fait il y en a deux, le QNaN et le SNaN pour Quiet et Signaling. Le QNaN (premier bit de la mantisse 1) signifie que le rsultat nest pas dtermin, et se propage dans la plupart des oprations arithmtiques. Le SNaN (premier bit de la mantisse 0) signifie que le rsultat est invalide et rsulte dans lappel de la fonction signal() en C ou la leve dune exception en Ada/C++, donc un plantage programm probable. Certains programmeurs scrupuleux initialisent les variables avec SNaN lors de la dclaration, de faon ce que leur usage avant une initialisation explicite dclenche une erreur tout de suite et indique le problme l o il est. L-dessus, quelques conventions de bon sens : Opration n non-zro 0 + 0 0 - 0 Rsultat 0 NaN NaN NaN NaN

Figure 7 - Conventions sur 0, et NaN.

11 / 29

3.2.2. Une solution parfois intressante : les rationnels


Un rationnel peut scrire sous une forme canonique rduite sous la forme +/- A/B o A et B sont entiers. Or, en perdant de la performance (voir paragraphe 3.1), on sait reprsenter des entiers, au besoin non limits par une borne prtablie ce qui ne veut pas dire infinis !-, de faon exacte sous rserve davoir assez de mmoire. Rappelons nous quelques vrits : Les constantes dclares de type rel crites dans un programme sont toujours des rationnels. En effet, crire X = 2.345 revient crire 2345/1000. Les valeurs imprimes aussi, puisquil ny a aucun moyen dcrire sur papier la valeur dun rel qui ne soit pas rationnel. Tout ce quon peut faire cest le dsigner (PI) ou donner une formule (racine de 2). Les calculs arithmtiques sur rationnels sont toujours absolument exacts, condition de ne pas tre limits par la taille de lentier, et cela vaut aussi pour la division. Si R1=A/B et R2=C/D, R1/R2 vaudra (A x D) / (B x C), donc les deux entiers reprsentant le rationnel (R1/ R2) sont calculables dans tous les cas de faon exacte.

Dans certaines applications o lexactitude du rsultat est primordiale, et o on peut se payer une reprsentation non borne des entiers (ce qui se termine gnralement par des tableaux de taille flexible), on peut se permettre de remplacer tous les rels par une structure ad-hoc compose de deux entiers dont lun est sign. Ceci suppose videmment quon na aucun besoin de fonctions transcendantes, ce qui casserait laspect exactitude mais par contre on peut en contrler lincertitude un niveau arbitraire.

12 / 29

3.3.

Les caractres
Figure 8 Une reprsentation du H

On appelle caractre la reprsentation graphique des symboles alphabtiques ainsi que les informations de contrle standard qui se retrouvent sur peu prs tous les terminaux : saut de ligne, de page, et divers contrles qui supposent toujours que le terminal est une machine crire. Pour coder les caractres, une solution simple est dutiliser une correspondance entre la combinatoire sur N bits et le tableau des caractres que lon veut reprsenter. En fait la solution la plus simple consiste ne pas utiliser de correspondance mais utiliser brutalement un type entier : le char de C est un entier sur 8 bits. Il peut dailleurs tre selon les compilateurs signed char ou unsigned char, et il faut se mfier de a si on veut utiliser le huitime bit.5 Toujours en C, il faut bien tre conscient que lcriture sous forme caractre avec les apostrophes, par exemple un A, nest quune autre manire dcrire un entier, ici 65 sauf codage exotique. Cest ainsi que A + 1 est valide et rend B ou 66 selon le format dcriture que lon souhaite. De mme, \0 nest quune faon complique dcrire 0 et \65 dcrire A ou 65. Faire une correspondance parat simple mais apporte plusieurs difficults : Il est commode de ne pas dpasser 8 bits pour des raisons videntes. Or la multiplicit des caractres possibles, mme sans aller chercher les hiroglyphes ou les idogrammes japonais ou chinois, fait que la limite des 256 est vite pulvrise. Historiquement, et si on passe sur le code Morse dont la principale bonne proprit est dtre longueur variable les caractres les plus frquents tant les plus courts), on a travaill sur 5 bits (32 positions, nettement insuffisantes : on en sacrifiait deux pour crer un contexte qui ddoublait les 30 autres. Code dit moments , ici Baudot.) Cest le codage tlgramme .6 6 bits : lanctre du codage ASCII : les 64 positions excluaient les minuscules et les caractres accentus. Une des contraintes imposes Ada qui devait tre universeltait de pouvoir scrire et se lister en caractres 6 bits. 7 bits : le codage ASCII actuel le plus utilis. 128 caractres. Les 32 premiers sont non imprimables , incluant la tabulation, le saut de ligne, lespace, etc.

Cest dire quen cas de doute, il faut mettre explicitement le mot-cl unsigned. Les 5 bits taient des tringles mtalliques qui jouaient les unes contre les autres et devaient tre graisses. Afin de dbourrer la machine avant lenvoi dun message, ceux-ci taient prfixs de squences de ZCZCZC et RYRYRY dont les codes activaient les barres en alternance. Aujourdhui encore, les tlgrammes sont prfixs de ZCZC et bien rares sont ceux qui savent do vient ce qui nest plus quune tradition.
6

13 / 29

3.3.1. Ascii

Figure 9 - Table ASCII 7 bits

Les codes dits Ascii tendus sur 8 bits ont la fcheuse proprit de ne pas tre standard. Voir ci-contre pour ce qui en est fait sur PC/DOS. L-dessus, labondance dalphabets mme dans le monde occidental (grec par exemple) fait que lutilisation de 8 bits est tout fait insuffisante si lon prtend grer simultanment plusieurs alphabets. On peut videmment nen grer quun la fois, et on se retrouve paradoxalement avec des codes moments comme du temps du code Baudot, c'est--dire que la comprhension dune squence de caractre dpend dun prfixe ou dun caractre spcial qui change tout. Faute de quoi on se retrouve avec des surprises coteuses, par exemple le code ayant prvu dimprimer un dollar ($) va tre excut sur une machine qui linterprtera comme une livre () et paf la facture.
Figure 10 - Table ASCII tendu sous DOS

3.3.2. EBCDIC
Cit ici pour mmoire, est un autre format de codage sur 8 bits, utilis exclusivement par IBM en plusieurs versions incompatibles entre elles, et aujourdhui plus ou moins obsolte. Il na gure servi qu rendre les clients captifs. 14 / 29

3.3.3. ISO 8859-1


Il sagit dun code dit latin , c'est--dire que lon a cherch y mettre les caractres de la plupart des pays qui ont des alphabets drivant, peu ou prou, de lalphabet latin tout en conservant la compatibilit avec lASCII 7 bits. Il ny a donc pas de caractres grecs ou cyrilliques. Le tableau ci-contre montre les extensions au code Ascii 7 bits (dans ce tableau le bit de gauche est toujours 1).
Figure 11 - ISO 8859-1

Au fait, contrairement une lgende bien implante, on accentue les majuscules en Franais (il suffit de lire un journal qui prend soin de sa typographie genre ou le JO pour sen convaincre). Cest pourquoi on a les , et autres dans les codes disponibles. Un seul bmol : dans le comit idoine, la reprsentation franaise ayant eu, dit-on, dautres chats grer le jour o ctait sur le tapis7, le E dans lO comme dans uf nest pas dans la liste et si je peux lcrire ici cest que Word nutilise pas ce standard. Une variante, le 8859-15, a introduit le symbole et le fameux .

3.3.4. UTF-8 (Universal Transformation Format)


Ce codage est une tentative de concilier la compatibilit entre lASCII 7 bits et les autres jeux de caractres (donc un programme prvu pour de lASCII fonctionnera en principe). Cest un code de taille variable de 1 4 octets. Lide est de sacrifier les bits de gauche pour indiquer combien doctets sont ncessaires. Si le premier bit est zro, la taille sera de un octet et les 7 autres reprsentent le caractre ASCII, ce qui rend UTF compatible avec ASCII (hlas les caractres accentus ne sont pas dans le jeu ASCII 7 bits et UTF est incompatible avec ISO 8859-1 dans la zone qui utilise le 8me bit, ce qui fait que seul les anglophones ont la compatibilit totale des trois codages ASCII, ISO 8859-1 et UTF8 pour leurs caractres courants.) Si le premier bit est un, cela signifier que le code prendra plusieurs octets, et il faut examiner le motif de bits pour savoir combien (le nombre de bits un avant le premier zro reprsente le nombre doctets du code). Les octets suivants commencent par 10, ce qui leur est rserv et cela permet de retomber sur ses pieds si daventure un octet se perd dans la transmission : on rcuprera le flux aprs le dernier octet commenant par 10. Donc : 0xxxxxxx => jeu de 128 caractres ASCII 110yyyyy 10xxxxxx => un octet de plus et 2048 combinaisons. 1110zzzzz 10yyyyyy 10xxxxxx et 11110ttt 10zzzzzz 10yyyyyy 10xxxxxx pareil permettant ainsi jusqu 21 bits de codage (en gnral on sarrte 3 octets, soit 16 bits de codage).

Autre lgende, celle du complot: lemployeur du reprsentant aurait fabriqu des imprimantes sans l.

15 / 29

On remarquera que 1/on pourrait en principe avoir jusqu 6 octets, on sarrte 4 2/plusieurs combinaisons peuvent reprsenter le mme code puisque chaque changement de nombre doctets inclut forcment toutes les combinaisons prcdentes, on ne retient que la plus courte, les autres sont illgales. Ainsi le symbole de lEuro , cod en Unicode (cf infra) par 8364, donnera : 11100010 10000010 10101100
1110 : 3 octets Reste expurg des drapeaux : 0010 0000 1010 1100 Soit 20AC en Hexa, soit 8364 dcimal

Alors que A, cod 65, aura en UTF8 la mme reprsentation quen ASCII : 01000001. Trs gros inconvnient : dans une chane de caractres, il faut courir depuis le dbut pour savoir quelques informations et entre autres la taille en terme de nombre de caractres pour le formatage des sorties. Cela nest pas un si gros inconvnient en C o le principe du stockage des chanes avec zro terminal implique davoir souvent courir depuis le dbut, mais dautres langages peuvent tirer parti de la taille dun tableau et de celle de llment, si elle est constante, pour calculer rapidement le nombre dlments. Il y a dans le mme ordre dide un UTF-16 qui prend 16 ou 32 bits avec le mme principe du prfixe interdit (ici 110110) et un UTF-32 toujours sur 32 bits (coder des codes dfinis par Unicode : cf infra). Tout cela se complique encore des deux options possibles en matire dendianit puisquil y a des squences doctets, et lentte de flux, fichier ou autre devra prciser si lon est en Big ou Little Endian. 8

3.3.5. Unicode

Figure 12 - Codage

Lide est dattribuer un code unique tous les caractres de la plante, aujourdhui plus de 100000 sont nomenclaturs. Ce code peut ensuite tre plaqu sur un UTF dont le principe a t dfini de faon conjointe. Loriginalit dUnicode par rapport aux autres systmes est que Unicode numrote des caractres abstraits et spare cette abstraction de la reprsentation. Unicode compte ainsi sur un moteur de rendu pour laffichage final. Unicode est donc un standard couches .
8

Ainsi, dans la couche haute, le caractre est nomm "Lettre majuscule latine c cdille". Dans la couche infrieure, il est cod par un nombre hexadcimal (00C7).

Voir encadr ce sujet, paragraphe 3.1.1.

16 / 29

En dessous, on va le plaquer sur un codage, par exemple UTF8 : ici 11000011 10000111 o les bits de C7 sont mis en gras. En dessous, on dcide de lendianit 9(ici il y a deux dcisions prendre : quel bit de chaque octet part en premier, et quel octet part en premier.) Enfin, on dcide des mcanismes de compression et de chiffrement qui vont encore changer la squence de bits, mais cette fois-ci de faon dpendante du message luimme.

Pour ce qui est de laffichage (ou de la lecture en cas de reconnaissance optique) la norme dlgue le rendu un moteur de rendu qui peut tre trs complexe cause des changements graphiques contextuels, ligatures etc. Ainsi le caractre a-t-il son numro, mais sa reprsentation est la somme dun a et dun ^, des glyphes et le moteur de rendu a le choix dappeler une reprsentation pr compose ou de la composer en appelant les deux glyphes. L-dessus, dans beaucoup de langues, le rendu dpend du contexte (ligatures diverses) ainsi Jacques crit en arabe jak donnera alors que kaj donnerait et que lnumration des trois lettres j a k espaces serait ( ici numres de gauche droite). Les caractres ne sont pas stocks dans lordre daffichage mais dans lordre dcriture, ce qui a son importance dans les documents bilingues o lon cite une phrase qui scrit dans lautre sens. Ainsi la ligne jak = sera-t-elle stocke par la squence de caractres j a k = . Bref, cest un standard qui demanderait lui tout seul un livre dexplications et qui sort du cadre de ce document sur la reprsentation des donnes. Le programmeur retiendra que les caractres Unicode demandent parfois des types spciaux (en C : wchar_t, inclure <wchar.h> peut reprsenter des squences Unicode mais cest assez mal dfini et cela risque de ne pas tre portable). Lcriture en C de plusieurs caractres entre deux apostrophes simples en devient autorise, source derreur si on voulait faire une chane de caractres normale et quon confond avec les doubles quotes. On notera aussi que de plus en plus de langages grent Unicode de faon native (Java).
F Figure 13 Dcodage

Voir encadr ce sujet, paragraphe 3.1.1.

17 / 29

3.3.6. Pinyin
Les asiatiques qui ont des alphabets gigantesques nont pas que le souci de les afficher : il faut pouvoir les taper sur des claviers de taille raisonnable. Une solution rpandue est dassocier chaque idogramme quelques lettres du clavier, choisies plus ou moins en raison de la ressemblance de la prononciation. Le scripteur tape donc sur un clavier normal notre sens et souvent il en voit lcho dans une toute petite fentre ou une bulle sous le curseur. Ds que les caractres sont reconnus comme tant un code valide, le caractre chinois apparat et la petite fentre est vide. Cette multiplication du nombre de caractres taper nest pas en soi un handicap, car les idogrammes, comme leur nom le suggre, sont souvent des mots complets ou des parties de mots.

3.3.7. Le CR
Figure 14 - Tltype chariot

Le CR (Carriage Return, retour chariot) a un nom qui vient du chariot des tltypes qui taient basiquement des machines crire lectriques tlcommandes. Cest pourquoi on distingue le CR (le chariot revient en arrire sur la mme ligne) du Line Feed (le tambour fait avancer la feuille) et aussi pourquoi on peut jouer avec le BackSpace (retour en arrire dune position) pour souligner (en mettant un blanc_soulign ensuite) ou effacer (en crivant autre chose).10 Le problme est que la marque actuelle de fin de ligne est devenue aujourdhui logique et arbitraire. On voit ainsi des systmes PC/Windows- demander la succession historique CR LF (le chariot revient en dbut de ligne, et le tambour avance le papier) alors que dautres se contentent de CR MacOs ancien - ou de LF Unix repris en C-. Dautres enfin nutilisent rien du tout et indiquent pour chaque ligne la longueur dicelle VMS-. Pour couronner le tout, la notion de retour la ligne et de retour arrire change si lon crit de droite gauche et il existe des documents bilingues dans lesquels les deux textes sont en vis--vis, ou simplement quand un texte en franais inclut une citation en hbreu. Tout ceci naurait aucune importance pour le programmeur si les systmes ne distinguaient pas les fichiers texte (ceux qui peuvent tre dits avec un diteur de texte) des fichiers binaires . Exemples de problmes : 1. La copie par FTP de fichiers dun systme un autre peut obliger convertir les marqueurs de fin de ligne. Cest pourquoi FTP a deux modes : texte (t) et binaire (b) ; le binaire ne fait aucun traitement, le texte corrige au vol tous les marqueurs de
10

Sur les systmes anciens la demande de mot de passe dans Username/Password tait prfixe de squences dans le genre CR XXXXXXXX CR ######## CR HHHHHHHH CR de faon que le mot de passe soit tap sur du papier dj obscurci. raison de quelques caractres par seconde, a prenait un temps considrable.

18 / 29

fin de ligne en changeant la convention du systme source en la convention du systme cible (noter que cela peut changer la longueur du fichier, si on passe de la convention CR LF/CR par exemple). Passer en binaire un fichier texte va conduire un fichier inditable (tout sur une ligne par exemple). Inversement, passer en texte un fichier binaire va conduire un fichier dont certains octets seront purement et simplement changs (syndrome classique des fichier images o des lignes fausses apparaissent ici et l : il se trouve quau hasard du codage un code CR tait dans le fichier et a t traduit, tort, en LF). Sauf si les systmes source et destination sont les mmes, auquel cas il ny aura pas de souci et le FTP ignorera simplement la commande binaire/texte et lutilisateur qui ne sait pas forcment quel est le systme distant ne comprendra pas pourquoi a ne marche plus sur Mac alors que a marchait hier sur PC. 2. Mme problme avec le mode "t"de fopen en C. Ce mode na aucune importance si on compile sur Unix o le marqueur de fin de ligne du langage se trouve tre le mme que celui du systme (fichier texte = fichier binaire) : dans ce cas l il est ignor. Mais si on compile sur PC, par exemple, toute occurrence de "\n" en C va tre traduite silencieusement en la squence CR LF sur disque pour que le fichier soit effectivement du texte ditable ; et inversement en lecture si et seulement si on est en mode "t" (texte). Si on est en mode "b", aucune conversion. Do surprises varies (le programme marche sous Unix mais pas sous Windows, la taille du fichier na rien voir avec le nombre doctets quon y a crits, etc.)

4. Les types structurs


4.1. Les tableaux (& chanes de caractres)

Un tableau est une collection dlments de mme type rfrencs par la valeur dun index. Ce qui est important dans cette dfinition est ce qui ny est pas : lindex nest pas forcment entier. Tout ce quon lui demande est dtre discret. Donc concrtement en Pascal ou Ada cela peut tre un type numr (Bleu Blanc Rouge) ou Character , cela peut tre un lment de N ou de N2, ou un lment du produit Character * N , etc. Dans ce cas on parle de tableau plusieurs dimensions.

4.1.1. En C
Les tableaux nexistent simplement pas ; tout ce qui y ressemble est un artifice d larithmtique sur pointeurs, part loprateur sizeof. La dclaration int T[100] ; est transforme en const int * T = (int *)malloc(100 *sizeof(int)) ; Lindexation T[45] est transforme en *(T+45) et la preuve la plus baroque est que par la commutativit *(T+45) est quivalent *(45+T) lui-mme quivalent 45[T] quipasse effectivement la compilation avec succs. Laffectation T1 = T2 ne concerne, dans le meilleur des cas (T1 pas constant), que ladresse des premiers lments. Il ny a AUCUNE vrification des bornes quand on indexe. La fin du tableau doit tre, soit connue du programmeur qui fait en sorte de ne pas dpasser et prie pour ne pas

19 / 29

faire derreur car elle ne sera probablement pas signale-, soit marque quelque part par un descripteur gr explicitement ou comme dans les chanes de caractres. Les tableaux sont ncessairement unidimensionnels. Tout tableau plusieurs dimensions nest in fine quun vecteur de vecteurs Dans le cas particulier des chanes de caractres, la fin du tableau est marque par le caractre NUL (0, ou \0) et cest la charge du programmeur (ou des fonctions quil utilise) que den tenir compte.

4.1.2. En Pascal, Ada, Vhdl


Les tableaux sont des abstractions gres par le langage. Concrtement, il y a des descripteurs de tableaux qui contiennent, sur quelques octets, les informations sur les index11, la taille de llment et ladresse du premier lment. Ce sont ces descripteurs qui sont viss par les variables de type tableau. Cette double indirection permet parfois le slicing (une tranche de tableau, vise par un descripteur spcifique, est vue comme un tableau de plein droit, autrement dit la mme mmoire peut tre vise par plusieurs descripteurs diffrents. cf figure). Descripteur 1 Borne basse Borne haute Adresse dbut Descripteur 2 Borne basse Borne haute Adresse dbut

Mmoire
Figure 15 - Descripteurs de tableaux

De mme, cette double indirection apporte de bonnes proprits comme : T1 := T2 ou if (T1 = T2) concernent tous les lments des tableaux. T[45] est une opration spcifique, c'est--dire pas dfinie par quivalence avec un jeu mmoire (ici syntaxe Pascal). Les tableaux peuvent tre multidimensionnels.

11

On peut imaginer de mettre, pour chaque index, ses limites et la taille de llment. Ou de considrer que le compilateur rduira tout un seul vecteur (avec des multiplications).

20 / 29

4.2.

Les enregistrements

Un enregistrement (record en Pascal, Ada, ou struct en C) est une structure qui rassemble plusieurs champs de type et taille ventuellement diffrents. Laccs, vu du ct du programmeur, se fait par nom et par la notation pointe. Ct machine, ce nom est remplac par un dcalage constant. Par exemple : struct { int a ; char b ; } toto ; toto.a vise la mme adresse que toto. toto.b vise toto+4 (supposant que sizeof(int) vaut 4). Cela dit, rien noblige le compilateur respecter lordre ni mme lexistence des champs spcifis. Ainsi, si loptimiseur dtermine que jamais tel champ nest utilis (en phase de dveloppement, par exemple, ou alors cest un champ qui ne sert que dans certains modes Debug) alors il peut simplement le supprimer la grande surprise du programmeur quand celui-ci fait un sizeof . De faon plus courante, considrons cet enregistrement (syntaxe Ada) type TOTO is record A :CHARACTER ; I :INTEGER ; B :CHARACTER ; end record ; Il est clair que limplmentation nave va demander trois mots mmoire (supposant que lentier demande un mot, il va tre cas entre deux mots qui ne contiendront chacun quun caractre). Le compilateur va vraisemblablement permuter les champs I et B, de faon coder le tout sur deux mots.

4.2.1. Clauses de reprsentation


En Ada, les clauses de reprsentations permettent de court-circuiter les dcisions du compilateur et de spcifier, au bit prs, o se trouve tel champ et sur combien de bits. Ceci fait partie de laspect systme dAda, et permet de programmer finement des drivers, par exemple. Ainsi, si un champ dun record est I :INTEGER range 0..3 ; (donc un entier permettant de compter de 0 3, codable sur deux bits), alors la clause de reprsentation associe dont jpargne au lecteur la description complte permet de dire : for I use at 16 range 10..11 ; ce qui signifie que lentier devra tre plac tel endroit du record (sur le mot qui commence au 16eme octet) et sur telle tendue (du 10me au 11me bit de ce mot) ; inutile de dire que le compilateur Ada sait compter et va rler si les dclarations sont incohrentes. Un effet prvisible mais quil faut grer, est que du coup il est possible de crer des champs qui nont pas dadresse en mmoire (par exemple le cas prcdent) parce quils sont au milieu dun mot ou cheval sur deux mots adressables. Certains cas de figure sont interdits, soit par 21 / 29

le langage soit par limplmentation (qui peut toujours lgalement refuser une clause de reprsentation), mais il arrive dans les cas de figure autoriss que cela cre des soucis : pensons au passage par rfrence, par exemple, qui nexiste pas en Ada prcisment pour viter le problme, mais que lon peut tre amen utiliser dans des interfaces. Dautre part, question efficacit, cela se paie trs cher : en effet le processeur doit procder plusieurs copies avant et aprs chaque opration arithmtique, lunit arithmtique tant dj assez complique comme a, on ne samuse pas lui permettre de faire des oprations sur des entiers cheval sur deux mots mmoire.

22 / 29

4.3.

Les variants

On appelle ainsi les objets qui sont vus sous plusieurs types diffrents suivant leur position dans le programme. Pourquoi faire une chose pareille ? Ecrire des programmes systme . On peut avoir besoin de contrler bit bit des objets que lon reoit sous dautres types, ou dcrire sous un type un objet qui sera relu sous un autre. Voir note 2 page 3. Gagner de la place : certains champs denregistrements nont de sens que si certains autres ont telle ou telle valeur (exemple classique en mdecine, selon le sexe du patient certains organes peuvent exister ou non ; la chose est facilement vrifiable mais pas en cours, sil vous plat). Dans ce cas, le mme champ sera vu sous deux types diffrents pour conomiser de la place disque (selon le champ sexe on mettra les donnes prostate ou les donnes utrus au mme endroit de lenregistrement), mais il nest pas question dcrire sous un type et de lire sous un autre, ce qui changerait un kyste de la prostate en grossesse.
Figure 16 Typage

(Hamster Jovial, Gotlib)

Faire des objets de taille variable : on peut avoir envie que la valeur dun champ conditionne la taille dun autre. Exemple, les chanes de caractres la Pascal, qui ont leur taille en tte et sont souvent dfinies comme un record deux champs, le premier tant la longueur utile du second.
Figure 17 Dtypage

(Affiche de Junior) Il y a plusieurs faons de jouer dtyper/retyper.

4.3.1. Le cast
Le plus simple est, comme en C, de le demander explicitement : cest le cast (au sens de moule, moulage : on fait fondre une pice pour en crer une autre). Ainsi : objet_de_type_2 = (type_2) valeur_de_n_importe_quel_type ; Ceci va effectivement provoquer le changement de type, sous quelques rserves ; en particulier les tailles doivent tre, sinon identiques, du moins compatibles selon le sens quen donne le compilateur. Mais au bilan, le tas de bits utilis pour reprsenter la valeur sera rinterprt dans le type_212. En Ada, on instanciera la fonction gnrique UNCHECKED_CONVERSION pour le mme usage.
12

Un des nombreux risques tant que le nouveau type considre ce motif de bits l comme invalide (voir par exemple les reprsentations de rels ou en UTF : il y a des motifs interdits ou qui provoquent des erreurs)

23 / 29

4.3.2. Lenregistrement variant


Il sagit de lutilisation de pseudo-enregistrements, c'est--dire que la mme zone mmoire sera vue comme tel type ou comme tel autre. En C, on dira union pour des raisons non documentes. Ainsi, lunion suivante : union TOTO { int PREMIER ; char SECOND[4] ; } OBJET; Permettra de voir la mme zone mmoire soit comme un entier (OBJET.PREMIER) soit comme un tableau de quatre caractres (OBJET.SECOND) qui pourra tre index : OBJET.SECOND[3] ;

Mmoire

int PREMIER OBJET

Mmoire

char SECOND[4]

Figure 18 Cast : le mme OBJET vu sous deux types diffrents

La mme chose est possible en Pascal la syntaxe prs (il y a un CASE dans le RECORD) mais en Ada, elle est divise en deux cas de figure qui ont chacun leur domaine dapplication :
Figure 19 Variants

Les variants non mutables; la dclaration est paramtre, mais les dclarations dobjets mettent une constante dans le paramtre et se retrouvent ainsi figs comme dhonntes objets statiques: type TOTO (B :BOOLEAN) is record case B is when TRUE => I:INTEGER; when FALSE => R:FLOAT; end case; end record; type TITI (I: INTEGER range 0..255) is record S:STRING(0..I); end record;

Mmoire

TRUE

I :INTEGER

Mme OBJET

FALSE

R :FLOAT

Mmoire

Mmoire

25

S :STRING(0..25) OBJET

Ici, chaque variable sera dclare avec une valeur du champ de slection qui ne pourra plus changer ensuite: V: TOTO(FALSE); ou ST: TITI(50); Dans le premier cas, seul le champ R existera, dans le second cas la chane S fera 50 caractres exactement. Cest le type qui est mutable, pas les variables. 24 / 29

Et les variants mutables, simplement marqus par le fait quils ont une valeur par dfaut. type TOTO (B :BOOLEAN:=TRUE) is record case B is when TRUE => I:INTEGER; when FALSE => R:FLOAT; end case; end record; type TITI (I: INTEGER range 0..255 :=50) is record; S:STRING(0..I); end record; Ici, les variables pourront recevoir des valeurs cres avec diffrentes valeurs du champ de slection par exemple on pourra faire un tableau dobjets ayant diffrentes variances. Mais les valeurs elles-mmes ne pourront pas tre cres avec une valeur et lues avec une autre (ceci est garanti par limpossibilit daffecter le champ de slection tout seul). Le type et les variables sont mutables, mais pas les valeurs. Autrement dit, on ne peut pas utiliser ce mcanisme en Ada pour faire lquivalent de ce quon fait avec lunion C. Rassurons nous, cela est possible avec la fonction gnrique UNCHECKED_CONVERSION instancier sur les deux types concerns.

25 / 29

5. Les pointeurs
5.1. Quest-ce que cest ?
La notion de pointeur est gnralement comprise comme tant identique celle dadresse. Cela est vrai dans le cas de C et de sa famille, pour lesquels la notion dadresse est dans le langage , en particulier pour les tableaux et la notion darithmtique sur pointeurs. Nanmoins cela nest pas le cas dans tous les langages. Ada et VHDL, par exemple, font une abstraction de cette notion sous le nom daccess. Ceci dit, il se trouve, par pure conjoncture, que ces temps-ci ladresse est gnralement identique au mot mmoire. Cela na pas toujours t et cela nest pas une fatalit. On a vu des systmes pagins (ladresse demandait deux mots mmoire, page et adresse taient sur 16 bits, et la page tait prrgler avant de demander ladresse.) On va probablement voir sous peu des adresses plus petites que le mot mmoire car 64 bits dadressage, cest beaucoup mme en comptant sur la loi de Moore qui dit, entre autres, que la capacit mmoire double tous les 18 mois (facteur 1000 tous les 15 ans): un systme demandant 64 bits dadressage pourrait adresser plus de 18 milliards de gigaoctets, on en a bien pour 50 ans avant de voir a sur notre bureau. La seule proprit sur laquelle on puisse vraiment compter, cest que la taille du pointeur est indpendante de la taille de lobjet vis. Cest pourquoi tous les langages modernes autorisent dune faon ou dune autre la dclaration de variables ou de types pointeurs alors que lobjet point nest pas encore dfini. Cest mme comme a et uniquement comme a que lon peut faire des structures de donnes rcursives.
Figure 20 Pointeur

(Santons Magali, Aubagne) 1/ dclarer un type pointeur (on ne sait pas encore sur quoi mais le compilateur sait combien de place il faudra rserver si on sen sert, cest lessentiel). 2/dclarer le type point dont un champ est le type pointeur, dont on connat la taille. Le compilateur revient alors en arrire pour informer le type pointeur de ce sur quoi il pointe. L-dessus, Ada oblige faire avant tout une prdclaration incomplte du type point pour viter un gag qui se produit parfois en Pascal et qui sort du cadre de ce document.

5.2.

Que se passe-t-il lors dun malloc et dun free ?

Tous les langages qui permettent de grer la mmoire (cette permission est puissante mais dangereuse : les langages comme Java ne le permettent pas) ont des fonctionnalits quivalentes (NEW/DISPOSE en Pascal, NEW/Unchecked Deallocation en Ada). Le malloc rserve une zone mmoire et en donne ladresse au programmeur. Le free rend la mmoire au systme qui pourra la redonner lors dun malloc ultrieur. Sans entrer dans un trait sur la gestion de la mmoire, quelques points retenir : Il faut bien que le gestionnaire marque quelque part quelles sont les zones rserves et celles qui sont libres. Quelque part cela ne peut tre quenmmoire. Une solution est de maintenir une carte de la mmoire dans une zone rserve (linconvnient est la taille de la carte qui sera grande mme pour de petites applications, sauf la rendre lastique ce qui fait 26 / 29

tomber dans des algorithmes de gestion de liste, cf solution suivante). Une autre est dajouter chaque bloc allou (en gnral avant le premier octet) des informations le liant aux autres blocs dans une sorte de liste chane. Illustration :

999998

Figure 21 Carte mmoire 1

Au dbut, aucune mmoire nest rserve. Un grand bloc mmoire (1000000 - 2) est disponible dun seul tenant. Les deux premiers mots sont initialiss : le premier est ladresse du premier bloc disponible ou, comme ici o cest le premier et le dernier, un marqueur de fin (ici zro) le second sa taille (ici 999998).

5.2.1. Malloc
On fait un malloc(1000). Le premier octet nous informe que le premier bloc libre est aussi le dernier et est ladresse 2, loctet suivant nous dit quil y a assez de place. Le gestionnaire va donc rendre le pointeur P=2 au programme et modifier la zone mmoire ainsi :

1002

1000

998996

P
Figure 22 Carte Mmoire 2

On note que : la taille du bloc allou est juste devant P, et le premier mot contient ladresse du premier bloc libre dont la taille disponible (ici 998996 soit 100000 1000 -2x2) est mise jour. Ainsi lors de lallocation suivante, le gestionnaire partant du dbut de la mmoire va courir sur cette sorte de liste chane et sarrter au premier bloc suffisamment grand pour le couper en deux (une partie rendue et une partie libre lie la liste) ou sur le marqueur de fin (ici 0) pour faire une erreur. Lerreur ne signifie pas forcment quil ny a pas assez de mmoire, mais peut signifier quil ny a aucun bloc assez grand do des stratgies dites de ramasse-miettes (garbage collection) pour concatner ensemble de petits blocs de mmoire.

5.2.2. Le Free
Lors dun free, le pointeur P est rendu au gestionnaire de programme. Celui-ci regarde le mot qui prcde P pour avoir la taille du bloc librer. Puis il insre ce bloc dans la freelist , la liste des blocs libres quil parcourra ensuite lors des prochains malloc.

27 / 29

5.2.3. Considrations pratiques


Cette prsentation est trs sommaire et ne rend pas compte de quelques difficults classiques. Diffrentes stratgies sont possibles, celle-ci tant la plus nave (elle aboutit miter la mmoire puisque lon sarrte au premier bloc assez grand pour fournir le malloc, alors quon pourrait chercher un bloc juste assez grand. Ce qui a dautres inconvnients. Le programmeur C retiendra ne particularit essentielle des pointeurs : larithmtique est autorise dessus (P+3 rend ladresse du quatrime objet point) mais la valeur particulire rendue par le malloc a quelque chose que nont pas les valeurs calcules : elle est dans la carte mmoire ! Dans les illustrations ci-dessus, la valeur rendue par malloc est prcde par les deux mots de service (taille du bloc, adresse du suivant quand il est libre). Ce qui nest videmment pas le cas de P+3. Hlas la fonction free na aucun moyen de distinguer les valeurs qui ont t rendues par malloc et ceux qui ont t calculs, puisquelles ont le mme type. Donc moins de faire une usine gaz pour vrifier dans quel cas on se trouve, lappel de free sur une valeur qui na pas t rendue par malloc va dtruire toute linformation du gestionnaire de mmoire en dtruisant (ici) la liste chane des blocs libres.. Les programmeurs Pascal et Ada nont pas ce souci, il leur reste comme aux programmeurs C celui, pas mince, de ne pas librer un bloc qui na pas t allou, et de ne pas utiliser un bloc pas allou ou dj libr. Les programmeurs Java ne peuvent simplement pas allouer et dsallouer, tout est fait dans leur dos par le systme. Le prix payer est la performance : en effet la gestion mmoire provoque souvent un brusque ralentissement du systme (le ramasse-miettes, par exemple, arrte toute gestion pendant son excution). Cela peut savrer simplement gnant (si lapplication est suffisamment petite et courte pour quon puisse se vautrer en mmoire, le ramasse-miettes est inutile mais le systme ne le sait pas a priori) ou carrment catastrophique si lordinateur de bord de la fuse balistique se met faire la sieste pour grer sa mmoire un moment non contrl.

28 / 29

6. Table des illustrations


Figure 1 Linformatique nest pas de la sorcellerie.................................................................... 2 Figure 2 Little Indian et Big Indian ............................................................................................ 4 Figure 3 Gulliver Lilliput ..................................................................................................... 5 Figure 4 Embarras causs par laddition de deux entiers relatifs ............................................ 6 Figure 5 - Roue codeuse ............................................................................................................. 8 Figure 6 - Le Savant Cosinus dans l'histoire du Pont Neuf ...................................................... 10 Figure 7 - Conventions sur 0, et NaN. .................................................................................. 11 Figure 8 Une reprsentation du H ......................................................................................... 13 Figure 9 - Table ASCII 7 bits ................................................................................................... 14 Figure 10 - Table ASCII tendu sous DOS .............................................................................. 14 Figure 11 - ISO 8859-1 ............................................................................................................ 15 Figure 12 - Codage ................................................................................................................... 16 FFigure 13 Dcodage ............................................................................................................ 17 Figure 14 - Tltype chariot .................................................................................................. 18 Figure 15 - Descripteurs de tableaux........................................................................................ 20 Figure 16 Typage ..................................................................................................................... 23 Figure 17 Dtypage .................................................................................................................. 23 Figure 18 Cast : le mme OBJET vu sous deux types diffrents ............................................. 24 Figure 19 Variants .................................................................................................................... 24 Figure 20 Pointeur .................................................................................................................... 26 Figure 21 Carte mmoire 1....................................................................................................... 27 Figure 22 Carte Mmoire 2 ...................................................................................................... 27 -:-

29 / 29