Forum |  HardWare.fr | News | Articles | PC | Prix | S'identifier | S'inscrire | Aide Recherche
360 connectés 

  FORUM HardWare.fr
  Programmation
  C

  [c] Passer l'adresse d'un tableau a 2 dim en parametre [OK]

 


 Mot :   Pseudo :  
 
 Page :   1  2
Page Précédente
Auteur Sujet :

[c] Passer l'adresse d'un tableau a 2 dim en parametre [OK]

n°708753
fif_x
Posté le 26-04-2004 à 15:42:16  profilanswer
 

Bonjour,
j'essaye de passer l'adresse d'un tableau à 2 dimensions en paramètre de ma fonction mais je n'y arrive point.
 
dans mon main, j'ai une variable :

Code :
  1. int Vector[10][10];


j'appelle ma fonction ainsi :

Code :
  1. Fonction(&Vector);


 
et ma fonction est déclarée comme suit :

Code :
  1. void Fonction (int *** Vector){ ... }


 
A la compilation, j'ai cette erreur là :
orion > gcc -o label SpectralRouting.c
SpectralRouting.c: In function `main':
SpectralRouting.c:62: warning: passing arg 1 of `Fonction' from incompatible pointer type
 
Donc je ne comprend pas d'où vient mon erreur ...
Pourtant en c, l'adresse d'un tableau d'entiers à 2 dimensions, c'est bien un int *** non ????  
 
Merci des réponses  :sleep:


Message édité par fif_x le 27-04-2004 à 10:44:54
mood
Publicité
Posté le 26-04-2004 à 15:42:16  profilanswer
 

n°708774
kadreg
profil: Utilisateur
Posté le 26-04-2004 à 15:52:31  profilanswer
 

Un programme en C, c'est comme un ciel d'été : c'est plein d'étoiles


---------------
brisez les rêves des gens, il en restera toujours quelque chose...  -- laissez moi troller sur discu !
n°708786
fif_x
Posté le 26-04-2004 à 15:59:30  profilanswer
 

:lol:
c sympa, mais ça m'aide pas beaucoup :)
 
J'ai mis trop d'étoiles dans mon ciel ?? heu, dans mon programme ??

n°708814
fif_x
Posté le 26-04-2004 à 16:18:57  profilanswer
 

Gros Doute :
 
si je fait

Code :
  1. Fonction (Vector);


 
avec une fonction

Code :
  1. void Fonction (int **Vector)


 
ça me passe une copie tu tableau ou bien l'adresse du 1er élément du tableau ???

n°708854
fif_x
Posté le 26-04-2004 à 16:43:33  profilanswer
 

J'ai trouvé une solution en faisant :
 

Code :
  1. void Fonction (int * Vector){...}


et

Code :
  1. Fonction (&Vector[0][0]);


 
Mais dans ma fonction, je ne peux plus faire  
 
 

Code :
  1. int *a;
  2. a = Vector[1][1];


 
gcc me sort à la compilation : subscripted value is neither array nor pointer
 
je ne comprend plus ...
Le passage du tableau en parametre est-il bon ???
 
Merci.

n°708913
sisicaivra​i
Life is Beautifullll
Posté le 26-04-2004 à 17:15:02  profilanswer
 

void Fonction (int* Vector)
...
Fonction(Vector)
?


---------------
blog dessins + srtCleaner | Ricoh R6 | K20d | MK-wii 5112-3549-9484 | en phase de déblablatisation depuis le 26 avril 2002 | Belgian Connection
n°708918
fif_x
Posté le 26-04-2004 à 17:21:46  profilanswer
 

non désolé ce n'est pas ça, le compilateur me dit toujours passing arg 1 of `Fonction' from incompatible pointer type  
 
 
Merci quand meme :)

n°708961
djdie
L'heure, c'est l'heure.
Posté le 26-04-2004 à 17:46:44  profilanswer
 

Lors du passage en paramètre d'un tableau à 2 dimensions le compilateur perd la taille de la dimension 2, qui est pourtant indispensable pour indexer correctement le tableau (car un tableau à deux dimensions, en mémoire, est "tout plat" ). Donc il y a plusieures manières de faire, par exemple :

Code :
  1. void foo1(int t[])
  2. /*
  3. dans ce contexte, c'est équivalent à :
  4. void foo1(int *t)
  5. */
  6. {
  7.    /* Accès par t[0] ... t[9] */
  8.    /* J'ai un doute que ce soit bien défini, mais logiquement oui */
  9. }
  10. void foo2(int t[][2])
  11. /*
  12. dans ce contexte, c'est équivalent à :
  13. void foo2(int (*t)[2])
  14. */
  15. {
  16.    /* Accès par t[0][0] ... t[4][1] */
  17. }
  18. void foo3(int *t, int d)
  19. {
  20.    /* Pour accéder l'élément t[i][j] :
  21.    
  22.    *(t + i * d + j)
  23.    
  24.    */
  25. }
  26. int main(void)
  27. {
  28.    int t[5][2];
  29.  
  30.    foo1(t[0]);
  31.    foo1(&t[0][0]);
  32.    foo2(t);
  33.    foo3(&t[0][0], 2);
  34.  
  35.    return 0;
  36. }


Message édité par djdie le 26-04-2004 à 17:47:58
n°708972
darkoli
Le Petit Dinosaure Bleu
Posté le 26-04-2004 à 17:54:11  profilanswer
 

Allez, soyons fou, je rajouterais même foo4 : :D

Code :
  1. int foo4(int* t, size_t l, size_t c)
  2. {
  3. /* Pour accéder l'élément t[i][j] */
  4. t[(i * c) + j]
  5. ...
  6. return 0;
  7. }

Ce qui permet, une fois à l'intérieur de la fonction, de connaître le nombre de lignes (l) et le nombre de colonnes (c).
Bon ce coup-ci c'est tout propre ! :D


Message édité par darkoli le 27-04-2004 à 08:34:43
n°709001
Taz
bisounours-codeur
Posté le 26-04-2004 à 18:37:32  profilanswer
 

pour les dimensions, utilisez le type prévu pour : size_t

mood
Publicité
Posté le 26-04-2004 à 18:37:32  profilanswer
 

n°709199
Kmikaz92
4ever
Posté le 26-04-2004 à 23:05:48  profilanswer
 

Pour passer un tableau 2D suffit de faire :

Code :
  1. void fonction(int** tab);


 
puis

Code :
  1. fonction(tab[][N]);


 

n°709202
djdie
L'heure, c'est l'heure.
Posté le 26-04-2004 à 23:10:49  profilanswer
 

kmikaz92 a écrit :

Code :
  1. fonction(tab[][N]);




Hum c'est déjà syntaxiquement faux...
 
Je crois que toutes les solutions "raisonnables" ont été données plus haut (si ce n'est qu'il aurait été en effet mieux d'utiliser size_t).

n°709215
Kmikaz92
4ever
Posté le 26-04-2004 à 23:29:35  profilanswer
 

Oops me croyait en PHP en fait :) Et encore je sais pas si ca marche en PHP mais je me souviens l'avoir fait...
Pour le size_t, c'est juste un typedef de unsigned... je pense pas que ca fasse bugger le programme. Mais il est mieux de l'utiliser oui.

n°709318
fif_x
Posté le 27-04-2004 à 09:10:08  profilanswer
 

Merci de toutes les réponses, c'est vraiment sympa :)
A+

n°709325
jagstang
Pa Capona ಠ_ಠ
Posté le 27-04-2004 à 09:16:30  profilanswer
 

plutôt que d'essayer de rajouter une * par là, ajouter un & par là, vaudrait mieux relire le chapitre sur les pointeurs

n°709369
fif_x
Posté le 27-04-2004 à 10:01:14  profilanswer
 

Alors j'ai testé un peu toute les solutions, elles marchent bien.
Mais pour mon second probleme qui était d'assigner l'adresse d'une case du tableau a une variable :
 

Code :
  1. int *ptr;
  2. ptr = tab[i][j]


j'avais une erreur de compilation.
 
J'ai réussi a contrer le problème en fesant :

Code :
  1. void foo3(int *tab, int d)
  2. {
  3. int *ptr;
  4. ptr = (tab + i * d + j);
  5. }


 
et ça marche très bien.
Merci à tous :jap: :jap: :jap: :jap:


Message édité par fif_x le 27-04-2004 à 10:01:54
n°709374
HelloWorld
Salut tout le monde!
Posté le 27-04-2004 à 10:05:06  profilanswer
 

Code :
  1. ptr = &tab[i][j];

?

n°709424
fif_x
Posté le 27-04-2004 à 10:43:57  profilanswer
 

oui, ça te parait peut-etre stupide. Et c'est surement pour ça que ça ne marchait pas :D

n°709505
HelloWorld
Salut tout le monde!
Posté le 27-04-2004 à 11:28:45  profilanswer
 

non non, regarde, j'ai rajouté un "&"

n°709548
Taz
bisounours-codeur
Posté le 27-04-2004 à 11:52:00  profilanswer
 

HelloWorld a écrit :

Code :
  1. ptr = &tab[i][j];

?

et il les connait comment les dimensions ton compilateurs ?

n°709705
HelloWorld
Salut tout le monde!
Posté le 27-04-2004 à 14:30:52  profilanswer
 

Citation :

Mais pour mon second probleme qui était d'assigner l'adresse d'une case du tableau a une variable :  
 
 
Code :
 
  int *ptr;  
  ptr = tab[i][j]  
   
 
 
j'avais une erreur de compilation.  

n°709732
jagstang
Pa Capona ಠ_ಠ
Posté le 27-04-2004 à 14:50:21  profilanswer
 

HelloWorld a écrit :

Citation :

Mais pour mon second probleme qui était d'assigner l'adresse d'une case du tableau a une variable :  
 
 
Code :
 
  int *ptr;  
  ptr = tab[i][j]  
   
 
 
j'avais une erreur de compilation.  




 
ça m'étonne pas...

n°709908
fif_x
Posté le 27-04-2004 à 16:28:14  profilanswer
 

HelloWorld a écrit :

non non, regarde, j'ai rajouté un "&"


 
Meme avec un '&' le compilateur ne voulait rien savoir, j'avais la même erreur

n°710900
Kmikaz92
4ever
Posté le 28-04-2004 à 14:29:07  profilanswer
 

Ba deja ya les dimensions qu'il faut indiquer.
Mais aussi, il faut delcarer un ptr de ptr non ?
int** ptr ; et non int* ptr ;
enfin je crois... ca fait lgt que j'ai pas fait de C.
 

n°711091
djdie
L'heure, c'est l'heure.
Posté le 28-04-2004 à 16:03:28  profilanswer
 

Faudrait pas tout mélanger quand même. Le code de HelloWorld est parfaitement correct, ou alors je n'ai pas compris la question initiale.

Code :
  1. int main(void)
  2. {
  3.    int tab[6][2];
  4.    int *p;
  5.    p = &tab[2][1];
  6.    return 0;
  7. }


Si tu parlais de passage de paramètres, des exemples ont été donnés plus haut.

n°711206
fif_x
Posté le 28-04-2004 à 17:55:23  profilanswer
 

Non, le passage de paramètre est bon, c'est dans ma fonction que j'avais un problème  

Code :
  1. void foo(int *tab, int d)
  2. {
  3. int *ptr;
  4. ptr = &tab[i][j];
  5. }


 
Cette derniere instruction ne passais pas au compilateur.
 
par contre celle la marche :

Code :
  1. void foo(int *tab, int d)
  2. {
  3. int *ptr;
  4. ptr = (tab + i * d + j);
  5. }


 
Et je n'ai plus d'erreur de compilation.
Mais je vois toujours pas pourquoi ptr = &tab[i][j]; ne marchais pas.

n°711212
darkoli
Le Petit Dinosaure Bleu
Posté le 28-04-2004 à 18:21:31  profilanswer
 

fif_x a écrit :


Code :
  1. void foo(int *tab, int d)
  2. {
  3. int *ptr;
  4. ptr = (tab + i * d + j);
  5. }



i et j  sont des variables globales ?

n°711443
djdie
L'heure, c'est l'heure.
Posté le 29-04-2004 à 00:42:17  profilanswer
 

fif_x a écrit :

Non, le passage de paramètre est bon, c'est dans ma fonction que j'avais un problème  

Code :
  1. void foo(int *tab, int d)
  2. {
  3. int *ptr;
  4. ptr = &tab[i][j];
  5. }


...
Mais je vois toujours pas pourquoi ptr = &tab[i][j]; ne marchais pas.


Ce n'est pas l'affectation qui est en cause, c'est simplement que tab[i][j] ne veut rien dire, car tab n'est pas un tableau à deux dimensions ! Peut importe qu'il soit un pointeur sur le premier élément d'un tel tableau, l'information est perdue lors du passage de paramètre, dans la procédure c'est un "simple" pointeur sur un int.
 
tab[i] est totalement équivalent à *(tab + i). En l'occurrence, cette expression est de type int. tab[i][j] est donc une tentative d'indexer une expression de type int, ce qui est illégal.
 
La seule solution est donc de passer explicitement la dimension de la seconde dimension en paramètre et de faire comme tu l'as fait:

Code :
  1. ptr = (tab + i * d + j);
  2. /* ou */
  3. ptr = &tab[i * d + j];


Message édité par djdie le 29-04-2004 à 00:43:02
n°711641
fif_x
Posté le 29-04-2004 à 11:43:02  profilanswer
 

Merci beaucoup de ta réponse, c'est très clair maintenant :D :jap:

n°720843
fif_x
Posté le 10-05-2004 à 16:22:38  profilanswer
 

Bonjour,
 
un autre petit problème me tracasse serieusement,
J'ai un fonction du style  

Code :
  1. void fonction (char name[][MAXCARINNAME])
  2. {
  3. ...
  4. }


 
Mon main :

Code :
  1. #define MACARINNAME 20
  2. int main ()
  3. {
  4. char **Names;
  5. int nb=10,i;
  6. Names = (char**) malloc (sizeof(char*)*nb);
  7. for (i=0;i<nb;i++)
  8.  nodeNames[i] = (char*) malloc (sizeof(char)*MAXCARINNAME);
  9. fonction (Names); //PROBLEME DE COMPILATION
  10. return 0;
  11. }


gcc me dit :
AVERTISSEMENT: passage de arg 1 de « fonction » d'un type pointeur incompatible
 
Je n'arrive pas à passer Names en paramètre de la fonction, je ne trouve pas le bon format :(


Message édité par fif_x le 10-05-2004 à 16:23:37
n°720869
darkoli
Le Petit Dinosaure Bleu
Posté le 10-05-2004 à 16:32:40  profilanswer
 

Ce serais déjà une bonne chose de vérifier que tes allocations mémoire se déroulent sans problème.

Code :
  1. char **Names=NULL;
  2. Names=(char**) malloc (sizeof(char*)*nb);
  3. if (Names == NULL)
  4. {
  5.   /* Message d'erreur */
  6.   exit(1);
  7. }

Tu as un tableau dont la longueur des chaines de caractères est fixe pourquoi "s'embêter" avec une deuxième dimension.

Code :
  1. char **Names=NULL;
  2. Names=(char*)calloc(sizeof(char)*nb*MAXCARINNAME);
  3. ...

Avec la fonction calloc tu auras déjà initialisé toutes tes chaines à "".
 
Pour accèder à la chaine N :

Code :
  1. strcpy(Names[N*MAXCARINNAME], "lapin" );
  2. fprintf(stdout, "%s\n", Names[N*MAXCARINNAME]);

Il faut faire attention à la longueur des chaines que tu copies, par exemple en utilisant strncpy.
Pour N entre 0 et nb-1.
MAXCARINNAME doit être égal au nombre maximal de caractère plus un (pour le fameux '\0').
 
Enfin le prototype de la fonction fonction devient :

Code :
  1. void fonction(char* name);

En espérant ne pas avoir dit trop de conneries. :D


Message édité par darkoli le 10-05-2004 à 21:26:01
n°720891
fif_x
Posté le 10-05-2004 à 16:41:34  profilanswer
 

Merci beaucoup je vais essayer avec ça :)

n°720900
djdie
L'heure, c'est l'heure.
Posté le 10-05-2004 à 16:47:45  profilanswer
 

Sans parler de la façon d'utiliser malloc, il est logique que le compilo gueule. Names est un char**. Après initialisation, il pointera ici sur le premier élément d'un tableau de char*, et chacun de ces char* pointera sur le premier élément d'un tableau de char (après initialisation dans la boucle). Ce n'est PAS la même chose qu'un tableau à deux dimensions, même si la syntaxe utilisée pour accéder aux éléments est la même.
 
De façon imagée, le tableau à 2 dimensions est "tout plat" en mémoire. Les éléments sont rangés les uns à côtés des autres, la vision des deux dimensions est purement logique mais tu pourrais tout aussi bien le voir comme un tableau à une seule dimension; c'est simplement de l'arithmétique sur les pointeurs.
 
Par contre dans la version utilisant malloc que tu as décrit, tu construis un tableau de pointeurs qui pointent chacun sur des tableaux. Cela ressemble à un tableau à 2 dimension mais cela n'en est pas un, les éléments ne sont pas contigus en mémoire et tu as une étape d'indirection supplémentaire.
 
Donc dans le cas présent, ta fonction doit donc simplement recevoir un char** en argument.
 
En gros dans le début de ce fil, tu tentais d'enfiler un tableau à 2 dimensions dans un char** et maintenant tu tentes d'enfiler un char** dans un tableau à 2 dimensions.....

n°720907
fif_x
Posté le 10-05-2004 à 16:51:55  profilanswer
 

tu fait prof de C djdie ? :)
 
Tu explique beaucoup mieux que mes anciens profs :D

n°720925
fif_x
Posté le 10-05-2004 à 17:08:00  profilanswer
 


Donc il faudrai que je passe à ma fonction un tableau a 2 dimensions "plats" (si j'ai bien compris).
 
Mais si je fait comme a proposé darkoli :

Code :
  1. Names = (char**) malloc (sizeof(char)*nb*MAXCARINNAME);
  2. ...
  3. strcpy(Names[i*MAXCARINNAME], "chien" ); /*pour accéder a l'élément i */


A l'exectution, j'ai un seg fault.

n°720929
djdie
L'heure, c'est l'heure.
Posté le 10-05-2004 à 17:11:25  profilanswer
 

Si tu veux utiliser ta fonction telle quelle tu dois déclarer un vrai tableau à deux dimensions :

Code :
  1. char Names[10][MAXCARINNAME];

n°720935
fif_x
Posté le 10-05-2004 à 17:16:46  profilanswer
 

Merci, mais le problème étant que je ne connais pas à l'avance la taille du tableau.
Donc je doit modifier le prototype de ma fonction.
 
L'autre problème c'est que dans mon programme, soit j'appelle ma fonction avec un Vrai tableau a 2 dimensions, soit je l'appelle avec un tableau a 2 dimensions alloué dynamiquement.
 
Est-ce possible de faire un prototype de fonction qui accepte les 2 types ???

n°721138
torpe23
Posté le 10-05-2004 à 20:27:49  profilanswer
 

Un truc pas mal que j'ai eu en cours ce matin:
 

Code :
  1. #define HEIGHT 100
  2. #define WIDTH 100
  3. typedef long tab2d [HEIGHT][WIDTH]
  4. int fonction(tab2d var){
  5.    var[0][0] = 0;
  6.    var[1][1] = 0;
  7.    return 0;
  8. }


 
Si vous pensez qu'il y a une erreur dans le typedef, lisez votre "kernighan et Ritchie"!


Message édité par torpe23 le 10-05-2004 à 20:28:07
n°721143
Taz
bisounours-codeur
Posté le 10-05-2004 à 20:31:13  profilanswer
 

je vois juste que sur un système 32bits, ton tableau fait 40ko et n'est évidemment pas souple du tout

n°721183
darkoli
Le Petit Dinosaure Bleu
Posté le 10-05-2004 à 21:27:02  profilanswer
 

fif_x a écrit :

Donc il faudrai que je passe à ma fonction un tableau a 2 dimensions "plats" (si j'ai bien compris).
 
Mais si je fait comme a proposé darkoli :

Code :
  1. Names = (char**) malloc (sizeof(char)*nb*MAXCARINNAME);
  2. ...
  3. strcpy(Names[i*MAXCARINNAME], "chien" ); /*pour accéder a l'élément i */


A l'exectution, j'ai un seg fault.


J'ai copié/collé ton code et j'ai oublié d'enlever une étoile ! :D

Code :
  1. Names = (char*) malloc (sizeof(char)*nb*MAXCARINNAME);

:D

mood
Publicité
Posté le   profilanswer
 

 Page :   1  2
Page Précédente

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  [c] Passer l'adresse d'un tableau a 2 dim en parametre [OK]

 

Sujets relatifs
[c++] Se rendre a une adresse url nouvel essaiTransformer une image monochrome en tableau de bit
procedure : passage de parametre[PHP] savoir si un tableau contient au moins un element ?
recuperer la premiere ligne d'un tableauAfficher un gif dans mon tableau d'affichage [edit]
Faire un tableau de variables d'une classe?[Dreamweaer Mx] : Pb d'espaces entre 'tableau de mise en forme'
passer des donnees comme avec un formulaire, mais sans formulaire...[Builder6] tableau pour un accès rapide et régulier de données?
Plus de sujets relatifs à : [c] Passer l'adresse d'un tableau a 2 dim en parametre [OK]



Copyright © 1997-2014 Hardware.fr SARL (Signaler un contenu illicite) / Groupe LDLC