Tableau bidimensionnel et pointeur

Résolu/Fermé
metalque89 Messages postés 33 Date d'inscription mercredi 3 octobre 2007 Statut Membre Dernière intervention 18 novembre 2008 - 29 nov. 2007 à 19:33
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 - 30 nov. 2007 à 19:53
Bonjour,

J'aimerai réaliser un petit programme a priori simple mais j'ai quelques problèmes...

Le but du programme est de mélanger aléatoirement les éléments d' un tableau de tableau mais je n'arrive même pas à inverser deux éléments.

Voici mon code:

void exchange (int *Tab)
{
int temp=Tab[2][2];
Tab[2][2]=Tab[3][3];
Tab[3][3]=temp;
}

Cette fonction recoit le pointeur de mon tableau et doit inverser 2 éléments (que j'ai choisi au hasard pour l'exemple).
Le message d'erreur est : invalide types 'int[int]' for array subscribt.
Cette fonction marche parfaitement pour un tableau unidimensionnel donc le problème est que le compilateur ne comprend pas que je veux utiliser un tableau bidimensionnel.

Est ce qu'il me manque une librairie? Quelles sont les fautes dans le codes?

Inutile de préciser que je débute dans la programmation en C++...

Merci
A voir également:

12 réponses

kilian Messages postés 8731 Date d'inscription vendredi 19 septembre 2003 Statut Modérateur Dernière intervention 20 août 2016 1 527
29 nov. 2007 à 19:50
Oui, en fait la raison est simple (enfin, c'est relatif...)

Un tableau:
int tab[50];
C'est en fait un pointeur.
Pour accéder à l'élément tab[0], tu peux faire *tab
Pour accéder à l'élément tab[1], tu peux faire *(tab+1)
etc...

Et qu'est ce qu'un tableau multidimensionnel? En fait c'est un tableau de tableaux.
int tab[2][50];
tab[2] est un tableau, donc un pointeur.
Et tab tout court est aussi un tableau, mais qui pointe sur des tableaux. C'est donc un pointeur vers un pointeur.

Il faut donc affiner le type de Tab ici pour préciser que c'est un pointeur vers un pointeur d'entiers:
void exchange (int **Tab)
{
int temp=Tab[2][2];
Tab[2][2]=Tab[3][3];
Tab[3][3]=temp;
}
0
bonsoir

ouh là là!

Désolé de te contredire kilian, mais ça n'est pas ça et ça m'étonnerait que ton exemple marche.

Un tableau et un pointeur, ce n'est pas du tout la même chose.
Un tableau, c'est une zone de mémoire qui contient de la place pour N variables de même type.
Un pointeur c'est une variable qui sert à contenir l'adresse d'une autre, peut-être le début d'un tableau, peut-être pas
Dans un tableau bidimensionnel d'entiers, il y a de la place pour M fois N entiers, il n'y a *aucun* tableau de pointeurs
Tu ne peux en aucun cas assimiler un int ** Tab à un int Tab [10][10].

pour répondre à Metalque89, regarde ta fonction
Tab est un int *
donc Tab[2] est un int, imaginons qu'il vaut 12
Tab[2][2] signifie donc 12[2] ????? ton message d'erreur te dit bien que tu as un int[int].
à ta place, je passerais à la fonction des pointeurs sur les 2 éléments à inverser :
 exchange (&Tab[2][2],&Tab[3][3]);

void exchange ( int * n1, int * n2) {
  int temp=*n1;
  *n1=*n2;
  *n2=temp;
}
0
mype Messages postés 2435 Date d'inscription jeudi 1 novembre 2007 Statut Membre Dernière intervention 16 août 2010 436
29 nov. 2007 à 22:56
killian a raison int **tab c'est pareil que tab[x][y]

pour echanger les tableaux il faudrait les passer tous les deux en parametres plutot :
void echange(int **tab1, int **tab2)
{
        int **temp;
        **temp = **tab1;
        **tab1 = **tab2;
        **tab2 = **temp;
}

0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 835
29 nov. 2007 à 23:07
Salut,

Si tu veux que ça marche :
void exchange (int Tab[5][5]) 
{
int temp=Tab[2][2];
Tab[2][2]=Tab[3][3];
Tab[3][3]=temp;
} 


J'ai mis void exchange (int Tab[5][5]) en pensant que ton tableau est de taille 5*5, bien sûr, tu dois le remplacer par la vraie taille de ton tableau. Tu pouvais également mettre void exchange (int Tab[][5]) ou void exchange (int *Tab[5]). Mais jamais oublier la colonne ;)

Cordialement
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
kilian Messages postés 8731 Date d'inscription vendredi 19 septembre 2003 Statut Modérateur Dernière intervention 20 août 2016 1 527
29 nov. 2007 à 23:21
J'insiste: un pointeur et un tableau c'est la même chose.
Et un tableau de tableau, c'est un pointeur de pointeur.
Désassemblez vos programmes si vous ne me croyez pas ;-)

D'ailleurs même pas besoin d'avoir recours à te telles extrémités.
On utilise des pointeurs pour l'allocation de tableau dynamique qu'on exploite ensuite comme des tableaux:
//-----Version statique-----
int tab[5][100];
tab[0][0] = 1;
//Peut aussi s'écrire
**tab = 1;


//-----Version dynamique-------
int **tab;
int i;
tab = (int **) malloc (sizeof(int) * 5);
for (i=0; i<100; i++)
{
    tab[i] = (int *) malloc(sizeof(int));
}
tab[0][0] = 1;
//Peut aussi s'écrire
**tab = 1;
0
kilian Messages postés 8731 Date d'inscription vendredi 19 septembre 2003 Statut Modérateur Dernière intervention 20 août 2016 1 527
29 nov. 2007 à 23:24
Encore plus de violence, j'ai même le droit de faire:
int tab[5][100];
int **ptab;

ptab = tab;

tab[0][1] = 1;

printf("%d", ptab[0][1]); //Affichera 1


printf("%d", *((*ptab)+1) ); //Affichera 1
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 567
29 nov. 2007 à 23:30
Salut,

J'insiste: un pointeur et un tableau c'est la même chose.

Quel toupet ;-DDDDDDDDDDD

En fait un pointeur c'est l'addresse du 1er élément d'un tableau et pour être plus violent les pointeurs sont associés au tableaux dans le sens que le nom de tableau est le pointeur sur le 1er élément du tableau

Allez je sors ------------------------------------------>

















-------------------------------------------------------------------------------> ;-DDDDDDDDD
0
kilian Messages postés 8731 Date d'inscription vendredi 19 septembre 2003 Statut Modérateur Dernière intervention 20 août 2016 1 527
29 nov. 2007 à 23:44
Oh ça va hein ! ;-)
Déjà que je fais rien qu'à faire des conneries dans ce thread.... :-/
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 567 > kilian Messages postés 8731 Date d'inscription vendredi 19 septembre 2003 Statut Modérateur Dernière intervention 20 août 2016
29 nov. 2007 à 23:49
Déjà que je fais rien qu'à faire des conneries dans ce thread

c'est normal, tu as perdu l'habitude ;-)
pas trop souvent sur ccm ;-))
0
kilian Messages postés 8731 Date d'inscription vendredi 19 septembre 2003 Statut Modérateur Dernière intervention 20 août 2016 1 527 > lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019
29 nov. 2007 à 23:51
Si ça y est chuis revenu. C'est parce que j'avais plus de connexion pendant deux mois....
0
kilian Messages postés 8731 Date d'inscription vendredi 19 septembre 2003 Statut Modérateur Dernière intervention 20 août 2016 1 527
29 nov. 2007 à 23:33
Oups, finalement vous avez raison, tab[x][y] et **tab ne se comportent pas de la même façon.
J'ai vérifié et mille excuses, oubliez mon baratin d'avant.

*se prosterne*

En fait ça marche avec une dimension mais pas avec plusieurs.

Pour un tableau statique genre tab[10][500], le programme va allouer une longue plage mémoire linéaire de 500*10 places d'entiers.

Pour un tableau dynamique genre **tab, toujours avec les mêmes dimensions, le programme va allouer 10 cases contigües de pointeurs. Et chacune de ces cases va pointer vers une plage de 500 cases d'entiers contigus. Mais ces différentes plages ne seront pas nécessairement l'une derrière l'autres.

Si tab est statique, alors pour arriver à tab[2][5], il faudra aller sur l'adresse pointée par tab + (5*2) case d'entiers (à priori ça se passe comme ça).
Si tab est dynamique, alors pour arriver à tab[2][5], il faudra aller dans (*(tab +2))[5], ce qui est tout à fait différent.

Encore une fois désolé...
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 835
29 nov. 2007 à 23:53
Salut

Si tu mets, void exchange (int **Tab), comme tu as mis dans ton premier post, ça ne marche pas, le compilateur ne pourra pas accéder à la bonne case mémoire sans connaitre le nombre de colonnes. Teste par toi-même.

Côté définition, le père a raison. Il ne faut pas confondre pointeur et tableau.
Un tableau, c'est une zone mémoire qui peut contenir plusieurs éléments consécutifs de même type.
Alors qu'un pointeur est une zone mémoire qui contient l'adresse d'une autre zone mémoire.

Il est vrai que très souvent, tout se passe pareil. Mais pourtant, la notion est bien différente.
Voilà pourquoi, en désassemblant, tu verras souvent la même chose ;)

Cordialement
0
kilian Messages postés 8731 Date d'inscription vendredi 19 septembre 2003 Statut Modérateur Dernière intervention 20 août 2016 1 527
30 nov. 2007 à 13:20
Si tu mets, void exchange (int **Tab), comme tu as mis dans ton premier post, ça ne marche pas, le compilateur ne pourra pas accéder à la bonne case mémoire sans connaitre le nombre de colonnes. Teste par toi-même.

C'est pas tout à fait ça. Le calcul pour trouver une case mémoire précise n'est pas géré pareil entre un tableau statique et un dynamique.
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 835
30 nov. 2007 à 19:53
Non faux.
N'oublie pas comment est géré la mémoire lors de l'allocation d'une matrice. Maintenant, si tu donnes aucune information au compilateur, comment peut-il gérer les différents accès aux cases mémoires ? Impossible, il faut au moins l'information de la longueur du nombre de colonne.

Cdt
0
metalque89 Messages postés 33 Date d'inscription mercredi 3 octobre 2007 Statut Membre Dernière intervention 18 novembre 2008 2
30 nov. 2007 à 16:03
Salut,

Eh bien un grand merci a vous tous, je m'attendais pas a tant d'engoument!!! :)
Je n'ai pas encore essayé les solutions proposées mais je suis sur que je trouverai mon bonheur.

Cordialement
0
metalque89 Messages postés 33 Date d'inscription mercredi 3 octobre 2007 Statut Membre Dernière intervention 18 novembre 2008 2
30 nov. 2007 à 17:45
Je viens de tester 2 solutions qui fonctionnent parfaitement:

void exchange (int Tab[5][5])
{
int temp=Tab[2][2];
Tab[2][2]=Tab[3][3];
Tab[3][3]=temp;
}

Merci à fiddy pour cette soluce et


exchange (&Tab[2][2],&Tab[3][3]);

void exchange ( int * n1, int * n2) {
int temp=*n1;
*n1=*n2;
*n2=temp;
}

Merci à le père pour cette soluce

Encore merci a tous ceux qui ont participer a cette discussion
0