Vous êtes sur la page 1sur 8

21/12/2015

LESTABLEAUX

Lestableaux

Cechapitreestlasuitedirectedespointeursetvavousfairecomprendreunpeuplusleurutilité.Vous

comptiezyéchapper?C'estraté!LespointeurssontpartoutenC,vousavezétéprévenus!

Danscechapitre,nousapprendronsàcréerdesvariablesdetype«tableaux».Lestableauxsonttrès

utilisésenCcarilssontvraimentpratiquespourorganiserunesériedevaleurs.

Nouscommenceronsdansunpremiertempsparquelquesexplicationssurlefonctionnementdes

tableauxenmémoire(schémasàl'appui).Cespetitesintroductionssurlamémoiresontextrêmement

importantes:ellesvouspermettentdecomprendrecommentcelafonctionne.Unprogrammeurqui

comprendcequ'ilfait,c'estquandmêmeunpeuplusrassurantpourlastabilitédesesprogrammes,

non?;­)

Lestableauxdanslamémoire

«Lestableauxsontunesuitedevariablesdemêmetype,situéesdansunespacecontiguenmémoire.

»

Bon,jereconnaisqueçaressembleunpeuàunedéfinitiondudictionnaire.Concrètement,ils'agitde«

grossesvariables»pouvantcontenirplusieursnombresdumêmetype

( long , int , char , double
(
long
,
int
,
char
,
double

…).

Untableauaunedimensionbienprécise.Ilpeutoccuper2,3,10,150,2500cases,c'estvousqui

décidez.Lafig.suivanteestunschémad'untableaude4casesenmémoirequicommenceàl'adresse

1600.

1600.

21/12/2015

Lestableaux

Lorsquevousdemandezàcréeruntableaude4casesenmémoire,votreprogrammedemandeàl'OS

lapermissiond'utiliser4casesenmémoire.Ces4casesdoiventêtrecontiguës,c'est­à­direlesunesà

lasuitedesautres.Commevouslevoyez,lesadressessesuivent:1600,1601,1602,1603.Iln'ya

pasde«trou»aumilieu.

Enfin,chaquecasedutableaucontientunnombredumêmetype.Siletableauestdetype

chaquecasedutableaucontiendraun

des

int
int
int
int

.Onnepeutpasfairedetableaucontenantàlafois

int
int

etdes

double
double

parexemple.

Enrésumé,voicicequ'ilfautretenirsurlestableaux.

,alors

Lorsqu'untableauestcréé,ilprendunespacecontiguenmémoire:lescasessontlesunesàla

suitedesautres.

Touteslescasesd'untableausontdumêmetype.Ainsi,untableaude

uniquementdes

int
int

,etpasautrechose.

Définiruntableau

int
int

contiendra

Pourcommencer,nousallonsvoircommentdéfiniruntableaude4

int tableau[4];

int
int

:

Voilà,c'esttout.Ilsuffitdoncderajouterentrecrochetslenombredecasesquevousvoulezmettre

dansvotretableau.Iln'yapasdelimite(àpartpeut­êtrelatailledevotremémoire,quandmême).

Maintenant,commentaccéderàchaquecasedutableau?C'estsimple,ilfaut

écrire

tableau[numeroDeLaCase]

.

Attention:untableaucommenceàl'indicen°0!Notretableaude4

1,2et3.Iln'yapasd'indice4dansuntableaude4cases!C'estunesourced'erreurstrès

courantes,souvenez­vous­en.

int
int

adonclesindices0,

Sijeveuxmettredansmontableaulesmêmesvaleursquecellesindiquéessurlafig.suivante,je

devraidoncécrire:

int tableau[4];

tableau[0] = 10; tableau[1] = 23; tableau[2] = 505; tableau[3] = 8;

Jenevoispaslerapportentrelestableauxetlespointeurs?

Enfait,sivousécrivezjuste

casedutableau.Faitesletest:

tableau

int tableau[4];

printf("%d", tableau);

,vousobtenezunpointeur.C'estunpointeursurlapremière

21/12/2015 Lestableaux Résultat,onvoitl'adresseoùsetrouve tableau : 1600
21/12/2015
Lestableaux
Résultat,onvoitl'adresseoùsetrouve
tableau
:
1600

Enrevanche,sivousindiquezl'indicedelacasedutableauentrecrochets,vousobtenezlavaleur:

int tableau[4];

printf("%d", tableau[0]);

10 Demêmepourlesautresindices.Notezquecomme tableau estunpointeur,onpeututiliserle symbole *
10
Demêmepourlesautresindices.Notezquecomme
tableau
estunpointeur,onpeututiliserle
symbole
*
pourconnaîtrelapremièrevaleur:

int tableau[4];

printf("%d", *tableau);

10
10

Ilestaussipossibled'obtenirlavaleurdelasecondecaseavec

+1).

Lesdeuxlignessuivantessontdoncidentiques:

*(tableau + 1)

(adressedetableau

tableau[1] // Renvoie la valeur de la seconde case (la première case étant 0) *(tableau + 1) // Identique : renvoie la valeur contenue dans la seconde case

Enclair,quandvousécrivez

+0case(c'est­à­dire1600).

tableau[0]

,vousdemandezlavaleurquisetrouveàl'adressetableau

Sivousécrivez

tableau[1]

,vousdemandezlavaleursetrouvantàl'adressetableau+1case(c'est­

à­dire1601).

Etainsidesuitepourlesautresvaleurs.

Lestableauxàtailledynamique

LelangageCexisteenplusieursversions.

Uneversionrécente,appeléeleC99,autoriselacréationdetableauxàtailledynamique,c'est­à­direde

tableauxdontlatailleestdéfinieparunevariable:

int taille = 5; int tableau[taille];

Orcelan'estpasforcémentreconnupartouslescompilateurs,certainsplanterontsurlasecondeligne.

LelangageCquejevousenseignedepuisledébut(appeléleC89)n'autorisepascegenredechoses.

Nousconsidèreronsdoncquefairecelaestinterdit.

Nousallonsnousmettred'accordsurceci:vousn'avezpasledroitd'utiliserunevariableentre

crochetspourladéfinitiondelatailledutableau,mêmesicettevariableestuneconstante!Letableau

doitavoirunedimensionfixe,c'est­à­direquevousdevezécrirenoirsurblanclenombre

21/12/2015

Lestableaux

correspondantàlatailledutableau:

int tableau[5];

Maisalors…ilestinterditdecréeruntableaudontlatailledépendd'unevariable?

Non,rassurez­vous:c'estpossible,mêmeenC89.Maispourfairecela,nousutiliseronsuneautre

technique(plussûreetquimarchepartout)appeléel'allocationdynamique.Nousverronscelabien

plusloindanscecours.

Parcouriruntableau

Supposonsquejeveuillemaintenantafficherlesvaleursdechaquecasedutableau.

Jepourraisfaireautantde

unpeulatailledenotrecodesiondevaitafficherlecontenudechaquecasedutableauuneàune!

printf
printf

qu'ilyadecases.Maisbon,ceseraitrépétitifetlourd,etimaginez

Lemieuxestdeseservird'uneboucle.Pourquoipasd'uneboucle

pratiquespourparcouriruntableau:

for
for

?Lesboucles

for
for

sonttrès

int main(int argc, char *argv[])

{

int tableau[4], i = 0;

tableau[0] = 10; tableau[1] = 23; tableau[2] = 505; tableau[3] = 8;

for (i = 0 ; i < 4 ; i++)

{

printf("%d\n", tableau[i]);

}

return 0;

} 10 23 505 8
}
10
23
505
8

Notreboucleparcourtletableauàl'aided'unevariableappelée

programmeursdonnentengénéralàlavariablequileurpermetdeparcouriruntableau!).

i
i

(c'estlenomtrèsoriginalqueles

Cequiestparticulièrementpratique,c'estqu'onpeutmettreunevariableentrecrochets.Eneffet,la

variableétaitinterditepourlacréationdutableau(pourdéfinirsataille),maiselleestheureusement

autoriséepour«parcourir»letableau,c'est­à­direaffichersesvaleurs!

Ici,onamislavariable

i

,quivautsuccessivement0,1,2,et3.Decettefaçon,onvadoncafficherla

valeurde

tableau[0]

,

tableau[1]

,

tableau[2]

et

tableau[3]

!

Attentionànepastenterd'afficherlavaleurde

lesindices0,1,2et3,pointbarre.Sivoustentezd'afficher

tableau[4]

tableau[4]

tableau[4] tableau[4]
tableau[4] tableau[4]
tableau[4]

tableau[4]

!Untableaude4casespossède

,vousaurezsoit

21/12/2015

Lestableaux

n'importequoi,soitunebelleerreur,l'OScoupantvotreprogrammecarilauratentéd'accéder

àuneadresseneluiappartenantpas.

Initialiseruntableau

Maintenantquel'onsaitparcouriruntableau,noussommescapablesd'initialisertoutessesvaleursà0

enfaisantuneboucle!

Bon,parcourirletableaupourmettre0àchaquecase,c'estdevotreniveaumaintenant:

int main(int argc, char *argv[])

{

 

int tableau[4], i = 0;

// Initialisation du tableau for (i = 0 ; i < 4 ; i++)

{

tableau[i] = 0;

}

// Affichage de ses valeurs pour vérifier for (i = 0 ; i < 4 ; i++)

{

printf("%d\n", tableau[i]);

}

return 0;

}

0 0 0 0 Uneautrefaçond'initialiser
0
0
0
0
Uneautrefaçond'initialiser

Ilfautsavoirqu'ilexisteuneautrefaçond'initialiseruntableauunpeuplusautomatiséeenC.

Elleconsisteàécrire

placezlesvaleursuneàuneentreaccolades,séparéespardesvirgules:

tableau[4] = {valeur1, valeur2, valeur3, valeur4}

.Enclair,vous

int main(int argc, char *argv[])

{

int tableau[4] = {0, 0, 0, 0}, i = 0;

for (i = 0 ; i < 4 ; i++)

{

printf("%d\n", tableau[i]);

}

return 0;

} 0 0 0 0
}
0
0
0
0

21/12/2015

Lestableaux

Maisenfait,c'estmêmemieuxqueça:vouspouvezdéfinirlesvaleursdespremièrescasesdu

tableau,toutescellesquevousn'aurezpasrenseignéesserontautomatiquementmisesà0.

Ainsi,sijefais:

int tableau[4] = {10, 23}; // Valeurs insérées : 10, 23, 0, 0

…lacasen°0prendralavaleur10,lan°1prendra23,ettouteslesautresprendrontlavaleur0(par

défaut).

Commentinitialisertoutletableauà0ensachantça?

Ehbienilvoussuffitd'initialiseraumoinslapremièrevaleurà0,ettouteslesautresvaleursnon

indiquéesprendrontlavaleur0.

int tableau[4] = {0}; // Toutes les cases du tableau seront initialisées à 0

Cettetechniqueal'avantagedefonctionneravecuntableauden'importequelletaille(là,çamarche

pour4cases,maiss'ilenavaiteu100çaauraitétébonaussi).

Attention,onrencontresouvent

:1,0,0,0.

Contrairementàcequebeaucoupd'entrevoussemblentcroire,onn'initialisepastoutesles

casesà1enfaisantcela:seulelapremièrecaseseraà1,lesautresserontà0.Onnepeut

doncpasinitialisertouteslescasesà1automatiquement,àmoinsdefaireuneboucle.

int tableau[4] = {1};

,cequiinsèrelesvaleurssuivantes

Passagedetableauxàunefonction

Vousaurezàcoupsûrsouventbesoind'affichertoutlecontenudevotretableau.Pourquoinepas

écrireunefonctionquifaitça?Çavanouspermettrededécouvrircommentonenvoieuntableauà

unefonction(cequim'arrange).

Ilvafalloirenvoyerdeuxinformationsàlafonction:letableau(enfin,l'adressedutableau)etaussiet

surtoutsataille!

Eneffet,notrefonctiondoitêtrecapabled'initialiseruntableauden'importequelletaille.Or,dansvotre

fonction,vousneconnaissezpaslatailledevotretableau.C'estpourcelaqu'ilfautenvoyerenplus

unevariablequevousappellerezparexemple

tailleTableau

.

Commejevousl'aidit,

fonctioncommeonl'auraitfaitavecunvulgairepointeur:

tableau

peutêtreconsidérécommeunpointeur.Onpeutdoncl'envoyeràla

// Prototype de la fonction d'affichage void affiche(int *tableau, int tailleTableau);

int main(int argc, char *argv[])

{

 

int tableau[4] = {10, 15, 3};

// On affiche le contenu du tableau affiche(tableau, 4);

return 0;

}

void affiche(int *tableau, int tailleTableau)

21/12/2015

{

int i;

Lestableaux

for (i = 0 ; i < tailleTableau ; i++)

{

printf("%d\n", tableau[i]);

}

} 10 15 3 0
}
10
15
3
0

Lafonctionn'estpasdifférentedecellesquel'onaétudiéesdanslechapitresurlespointeurs.Elle

prendenparamètreunpointeursur

poursavoirquands'arrêterdanslaboucle!).

Toutlecontenudutableauestaffichéparlafonctionviauneboucle.

int
int

(notretableau),ainsiquelatailledutableau(trèsimportant

Notezqu'ilexisteuneautrefaçond'indiquerquelafonctionreçoituntableau.Plutôtqued'indiquerque

lafonctionattendun

int *tableau

,mettezceci:

void affiche(int tableau[], int tailleTableau)

Celarevientexactementaumême,maislaprésencedescrochetspermetauprogrammeurdebienvoir

quec'estuntableauquelafonctionprend,etnonunsimplepointeur.Celapermetd'éviterdes

confusions.

J'utilisepersonnellementtoutletempslescrochetsdansmesfonctionspourbienmontrerquela

fonctionattenduntableau.Jevousconseilledefairedemême.Iln'estpasnécessairedemettrela

tailledutableauentrelescrochetscettefois.

Quelquesexercices!

Jenemanquepasd'idéesd'exercicespourvousentraîner!Jevousproposederéaliserdesfonctions

travaillantsurdestableaux.

Jedonnejustelesénoncésdesexercicesicipourvousforceràréfléchiràvosfonctions.Sivousavez

dumalàréalisercesfonctions,rendez­voussurlesforumspourposervosquestions.

Exercice1

Créezunefonction

(utilisezun

return sommeTableau

return

sommeTableau

return sommeTableau

quirenvoielasommedesvaleurscontenuesdansletableau

pourrenvoyerlavaleur).Pourvousaider,voicileprototypedelafonctionàcréer:

int sommeTableau(int tableau[], int tailleTableau);

Exercice2

Créezunefonction

moyenneTableau

quicalculeetrenvoielamoyennedesvaleurs.Prototype:

double moyenneTableau(int tableau[], int tailleTableau);

Lafonctionrenvoieun

double
double

carunemoyenneestsouventunnombredécimal.

21/12/2015

Exercice3

Lestableaux

Créezunefonction

tableaudevraêtrecopiédanslesecondtableau.

Prototype:

copierTableau

quiprendenparamètredeuxtableaux.Lecontenudupremier

void copie(int tableauOriginal[], int tableauCopie[], int tailleTableau);

Exercice4

Créezunefonction

ayantunevaleursupérieureàunmaximum.Cettefonctionprendraenparamètresletableauainsique

lenombremaximumautorisé(

à

maximumTableau

quiaurapourrôlederemettreà0touteslescasesdutableau

).Touteslescasesquicontiennentunnombresupérieur

valeurMax

valeurMax

doiventêtremisesà0.Prototype:

void maximumTableau(int tableau[], int tailleTableau, int valeurMax);

Exercice5

Cetexerciceestplusdifficile.Créezunefonction

tableaudansl'ordrecroissant.Ainsi,untableauquivaut

valoir

Prototype:

ordonnerTableau

ordonnerTableau

ordonnerTableau {15, 81, 22, 13}
ordonnerTableau {15, 81, 22, 13}
{15, 81, 22, 13}

{15, 81, 22, 13}

quiclasselesvaleursd'un

doitàlafindelafonction

{13, 15, 22, 81}

.

void ordonnerTableau(int tableau[], int tailleTableau);

Cetexerciceestdoncunpeuplusdifficilequelesautres,maistoutàfaitréalisable.Çavavousoccuper

unpetitmoment.

Faites­vousunpetitfichierdefonctionsappelé

homologue

fonctionsdevotrecruréalisantdesopérationssurdestableaux.

tableaux.c

(avecson

tableaux.h

quicontiendralesprototypes,biensûr!)contenanttoutesles

Autravail!:­)

Enrésumé

Lestableauxsontdesensemblesdevariablesdumêmetypestockéescôteàcôteenmémoire.

Latailled'untableaudoitêtredéterminéeavantlacompilation,ellenepeutpasdépendred'une

variable.

Chaquecased'untableaudetype

int
int

contientunevariabledetype

Lescasessontnumérotéesviadesindicescommençantà0

:

tableau[0]

tableau[1]

,

tableau[2]

,etc.

int .
int
.