Taille d'un tableau dans un sous programme

Signaler
Messages postés
9
Date d'inscription
lundi 12 juillet 2004
Statut
Membre
Dernière intervention
25 septembre 2006
-
Messages postés
475
Date d'inscription
dimanche 3 octobre 2004
Statut
Membre
Dernière intervention
11 août 2006
-
Salut, je cherche a conna^tre la taille de mon tableau une fois qu'il
est passé en argument dans un sous programme. Pour l'instant, j'ai
cette déclaration :

void fermee(int piste[],const int lgth);



et dans mon main j'ai :

int piste[6];

int lgth=sizeof(piste)/sizeof(piste[0]);

fermee(piste,lgth);



je voudrais passer piste[] comme seul argument dans ma procédure fermee, donc j'ai mis :



void fermee(int piste[])

{

int lgth=sizeof(piste)/sizeof(piste[0]);
printf("%d",lgth);

}



il m'affiche alors un. Quand j'affiche séparément sizeof(piste) et sizeof(piste[0]), il m'affiche "4". Mais quand je les affiches à partir du main, tout marche bien : sizeof(piste) affiche "24" et sizeof(piste[0]) affiche "4".

Pourquoi cela ne marche pas dans la procédure?

Merci de votre aide.

16 réponses

Messages postés
207
Date d'inscription
jeudi 3 avril 2003
Statut
Membre
Dernière intervention
2 novembre 2006

C'est tout simplement parce que int piste[] correspond à int* piste, un poiteur

=> les pointeurs ont tous une longueur de 4 octets, d'où le 4 renvoyé dans ta procédure



Dans le main, par contre, int piste[6] n'est pas un pointeur, sa taille est : 6 * sizeof(int) = 24



Le mieux est de garder un argument "taille" => comme dans la plupart des fonctions Windows, voire DOS.



Si tu veux vraiment utiliser un unique argument :

- Place une valeur arbitraire marquant la fin (du genre 1024 ou -1....)

- Fait une recherche de cette valeur :



int len=0;

while( true )

{

if( Piste[len] != 1024 ) // 1024 = marquage

len++;

else

break;

}



Voilà, c tout ce que j'en pense
Messages postés
230
Date d'inscription
mercredi 11 février 2004
Statut
Membre
Dernière intervention
4 août 2005

Tu ne peux pas passer un tableau comme arguments, c'est un pointeur sur le prmier éléments que tu passes c'est pour ca qu'il te met 4
essaye
{


int tab[]=piste;
int lgth = sizeof(tab)/sizeof(int);
}
mais je suis pas sur que ca marche
a+
Messages postés
207
Date d'inscription
jeudi 3 avril 2003
Statut
Membre
Dernière intervention
2 novembre 2006

Ca ne marchera pas, en tout cas je ne pense pas :

int tab[] = piste

=> étant donné que tu ne définis pas le nombre d'éléments, le compilateur le transformera en un pointeur.

sizeof(tab) = 4



C'est mon avis, j'ai pas vérifié
Messages postés
9
Date d'inscription
lundi 12 juillet 2004
Statut
Membre
Dernière intervention
25 septembre 2006

okay je vous remercie. La deuxième solution n'est pas possible, donc je vais rester sur mon premier choix.

A+
Messages postés
207
Date d'inscription
jeudi 3 avril 2003
Statut
Membre
Dernière intervention
2 novembre 2006

Sage décision
Messages postés
475
Date d'inscription
dimanche 3 octobre 2004
Statut
Membre
Dernière intervention
11 août 2006
4
c'est possible en c++ en passant le tableau par reference



void fermee(int (&piste)[6])


{


int lgth=sizeof piste / sizeof piste[0];

}



il faut eviter d'utiliser sizeof avec des parantheses pour les identificateurs
Messages postés
207
Date d'inscription
jeudi 3 avril 2003
Statut
Membre
Dernière intervention
2 novembre 2006

Tu perds tout l'interet :

lgth de renverra 6, car tu as bloqué le nombre déléments du tableau à 6 !
Messages postés
475
Date d'inscription
dimanche 3 octobre 2004
Statut
Membre
Dernière intervention
11 août 2006
4
a oui ?



template <typename T, std::size_t S>



void fermee(T (&v)[S])


{


int lgth=sizeof v/ sizeof v[0
];

}





et la
Messages postés
207
Date d'inscription
jeudi 3 avril 2003
Statut
Membre
Dernière intervention
2 novembre 2006

Là, ça devrait aller mieux
Messages postés
6535
Date d'inscription
lundi 16 décembre 2002
Statut
Modérateur
Dernière intervention
22 août 2010
7
Ah oui steve_clamage, c'est beaucoup plus simple comme ca! Malheuresement on ne peut plus passer de pointeurs...
Messages postés
6535
Date d'inscription
lundi 16 décembre 2002
Statut
Modérateur
Dernière intervention
22 août 2010
7
Ah si pardon, on peut sans doute passer des pointeurs... mais dans ta
solution c'est comme si on passait aussi la taille en paramètre.
Messages postés
475
Date d'inscription
dimanche 3 octobre 2004
Statut
Membre
Dernière intervention
11 août 2006
4
C'est simple, une reference c'est un alias, un synonime de l'identificateur.
Messages postés
18
Date d'inscription
lundi 5 juillet 2004
Statut
Membre
Dernière intervention
15 avril 2009

Hello, puisqu'on est dans les tableaux, je poste ma question ici : j'essaie de faire une fonction qui redimensionne une matrice (tableau 2-D) allouée dynamiquement en prenant pour params les ancienne et nouvelle tailles. Même si le compilo ne signale pas d'erreurs, les progs utilisant cette fonction plantent parfois, pas à tous les coups. Voici la fonction, si quelqu'un peut m'expliquer le blème ça me fera p'tetre progresser :

void RszTab(int** &tab, int oldx,int oldy, int newx, int newy)
{
int **matrice = new int*[newy];
for (int i=0;i<newy;i++) matrice[i] = new int[newx];
for (int i=0;i<newx;i++) for (int j=0;j<newy;j++) matrice[j][i]=0;

if ((oldx<=newx)&&(oldy<=newy)) for (int j=0;j<oldx;j++) for (int i=0;i<oldy;i++)
matrice[i][j] = tab[i][j];
if ((oldx<=newx)&&(oldy>newy)) for (int j=0;j<oldx;j++) for (int i=0;i<newy;i++)
matrice[i][j] = tab[i][j];
if ((oldx>newx)&&(oldy<=newy)) for (int j=0;j<newx;j++) for (int i=0;i<oldy;i++)
matrice[i][j] = tab[i][j];
if ((oldx>newx)&&(oldy>newy)) for (int j=0;j<newx;j++) for (int i=0;i<newy;i++)
matrice[i][j] = tab[i][j];

for (int i=0;i<oldy;i++) delete[] tab[i];
delete[] tab;
tab = matrice;
}

Il y a certes des classes permettant de faire des manips sur les tableaux, mais ça serait pédagogique de capter mon erreur. Merci !
Messages postés
6535
Date d'inscription
lundi 16 décembre 2002
Statut
Modérateur
Dernière intervention
22 août 2010
7
Pense a vérifier que tes allocation ont été bien faites (excaption
bad_alloc je crois, ou pointeur NULL). Et puis tu peux un peu
simplifier ton truc:




int x min(oldx, newx), y min(oldy, newy)

for (int j=0;j<=x;j++)

  for (int i=0;i<=y;i++)

    matrice[i][j] = tab[i][j];

Messages postés
18
Date d'inscription
lundi 5 juillet 2004
Statut
Membre
Dernière intervention
15 avril 2009

Thanks !
Messages postés
475
Date d'inscription
dimanche 3 octobre 2004
Statut
Membre
Dernière intervention
11 août 2006
4
Cela peut poser de graves (tres graves) problemes de performances de
considerer que int** est un tableau 2d alors que la représentation
mémoire pour moi est un tableau de pointeur, travailler avec une
mémoire fragmentée est tout sauf cache-friendly.



De meme parcourir de cette maniere



for (int j=0;j<=x;j++)


for (int i=0;i<=y;i++)


matrice[i][j] = tab[i][j];



va poser de gros problemes car les données sont chargée dans le cache
par blocs continues (streams), il y aura à chaque itération un page
fault



Il est conseillée de faire :



int matrice[4][4]; // pour une matrice de 4 * 4

et



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


for (int j=0;j<4;++j)


matrice[i][j] = // pour l'indexer, jamais
matrice[j][i] !




Pour faire des calculs matriciels sur des matrices de taille dynamique,
il existe des bibliothèques optimisées pour ca (MTL, je ne sais pas si
la taille doit etre connue à la compilation).



Une autre solution plus simple est de faire une classe matrice
implémenté avec un std::valarray (tableaux dynamiques optimisées pour
les calculs vectoriels) en surchargeant par exemple operator () pour
garder l'indexation naturelle...