Salut,
Un tableau est, en effet, déclaré sous la forme généreique de
TYPE NomTableau[taille tableau]
L'astuce, c'est que NomTableau est alors en réalité un pointeur de TYPE, et qu'à ce titre, il ne sait qu'une chose: de combien de case mémoires il doit se décaler pour trouver l'élément suivant du tableau.
Tant que tu travailles dans la portée dans laquelle tu as déclaré ton tableau (on va dire que tu l'a déclaré statitquement
), tu sais de combien d'éléments il est composé...
Ainsi, si dans main(), tu écris:
1 2 3 4 5 6
|
int main(int argc, char* argv[])
{
int entier[10];
//la suite du prorgramme
} |
tu sais pouvoir utiliser les entiers allant de entier[0] à entier[9] inclus.
Tu déclare, par la meme occasion, un pointeur de type int et nommé entier
(int *entier
) qui pointe sur le premier élément de ton tableau (entier[0])
Seulement, quand tu va créer une fonction dans laquelle tu va fournir ton tableau d'entier en parametre sous la forme de
1 2
|
int MaFonction(int argtab[]) |
et que tu l'appellera sous la forme de
dans main(), tu passera en fait... le pointeur vers ton tableau.
Or un pointeur de tableau ne connait pas le nombre d'éléments qui le composent...
Bien sur, toi, tu sais que entier est un tableau de 10 entiers... Mais peux tu etre tout à fait sur que tu n'essayeras jamais d'appeler MaFonction en fournissant un autre tableau que le tableau entier?
Et que ce passerait-il si, dans MaFonction, tu te basais d'office sur une taille de tableau de 10 entiers?
Deux solutions sont envisageables, et susceptibles de poser des problemes:
Soit tu fournis un tableau de moins de dix entiers (int montab9[9]), soit tu fournis un tableau de plus de dix entiers (int montab11[11]).
Dans le premier cas (en fournissant un tableau de 9 entiers seulement), si tu fais une boucle du genre de
1 2 3 4 5
|
for(int i=0;i<10;i++)
{
//acces à argtab[i];
} |
Les éléments de tableau allant argtab[0] à argtab[8] réagiront correctement... mais argtab[9], ne faisant plus partie du tableau aura un comportement indéfini.
Tu ne peux en effet absolument pas etre certain de ce qui se trouve dans la case mémoire correspondant à argtab[9] 
Avec *beaucoup de chance*, les cases mémoires ne contiennent que des "crasses", mais avec "moins de chance", et ce sera le cas le plus fréquent, les cases mémoires contiennent des données utilisées ailleurs... et ta boucle ira peut etre modifier ces valeurs...
Le deuxième cas est un peu moins problèmatique, mais provoqueras des erreurs de calcul...
En effet, imaginons trente secondes que tu veuille obtenir la somme des valeurs mises dans le tableau.
En te basant sur le fait que tu as 10 éléments du tableau, tu fera une boucle du genre de
1 2 3 4 5 6
| int somme=0;
for(int i=0;i<10;i++)
{
somme+=argtab[i];
}
return somme; |
Sauf que, si tu passe un tableau de 11 entiers (montab11), tu ne caculeras jamais que... la somme des dix premiers (et que le résultat envoyé ne sera donc pas juste)...
Donc, pour que ta fonction puisse travailler aussi bien avec un tableau de 9 entiers qu'avec un tableau de 128 entiers, il faut lui donner une information complémentaire: le nombre d'éléments compris dans le tableau...
MaFonction devient donc
1 2 3 4 5 6 7 8 9
| int MaFonction(int argtab[], int taille)
{
int somme=0;
for(int i=0;i<taille;i++)
{
somme+=argtab[i];
}
return somme;
} |
et son appel devient
1 2 3 4 5 6
|
MaFonction(entier, 10);
//OU---OU---OU---
MaFonction(montab9,9);
//OU---OU---OU---
MaFonction(montab11,11); |
et cela pourra fonctionner quelle que soit la taille du tableau fournis en parametre
Partager