Retourner un tableau multi dimensionnel...

Retourner un tableau multi dimensionnel... - C - Programmation

Marsh Posté le 10-01-2006 à 17:31:19    

bonsoir,
 
un petit souci :
j'ai déclaré une structure :
 
typedef struct _maStruct {
char i ;
char j ;
} maStruct ;
 
Ensuite je cree un tableau multidimensionnel de pointeurs de cette structure:
maStruct* tab[4][4] ;
 
je veux une fonction getStruct() qui me renvoie ce tableau multi.
 
Le typedef de la structure, la definition du tableau et la fonction getStruct() sont dans un module.c
Je veux appeller getStruct() a partir de mon main.c (grace a un include "module.h" )
j'ai un probleme pour le prototype de ma fonction getStruct !
je pensais faire dans module.c un :
 
maStruct* tab[4][4] ;
maStruct* getStruct() {
return tab[4][4] ;
}
 
et appellé par main.c comme ceci :
 
maStruct* toto[4][4] ;
toto[4][4] = getStruct() ;
 
mais il y a une incompatibilité de type...
quelqu'un aurait-il une idée ?
merci

Reply

Marsh Posté le 10-01-2006 à 17:31:19   

Reply

Marsh Posté le 10-01-2006 à 19:35:12    

fabrice91 a écrit :


j'ai déclaré une structure :
 
typedef struct _maStruct {
char i ;
char j ;
} maStruct ;
 
Ensuite je cree un tableau multidimensionnel de pointeurs de cette structure:
maStruct* tab[4][4] ;
 
je veux une fonction getStruct() qui me renvoie ce tableau multi.


Une fonction ne sait pas retourner un tableau. Elle peut éventuellement retourner l'adresse du premier élément du tableau. C'est assez compliqué et je conseille l'encapsulation dans une structure. Ca permet en plus de conserver la taille...


struct mesdonnees
{
   maStruct* tab[4][4] ;
   size_t n;
};
 
{
   struct mesdonnees data;
 
  data_init (&data, 123);
 
}


avec (version ultra simplifiée).


void data_init (struct mesdonnees *p_data, size_t n)
{
   p_data->tab = malloc (sizeof *p_data->tab * n);
 
   p_data->n = n;
}


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 10-01-2006 à 20:57:15    

Merci pour la réponse, je m'étais mal exprimé et c'etait bien le pointeur sur le tableau que je voulais retourner...
Ensuite j'ai oublié de dire  :ange:  que ma solution fonctionnait mais que j'avais un Warning de compilation mais qui n'arrive qu'une fois sur deux !!!
Exemple :
je compile mon source->warning
je le fais tourner, pas de souci tout marche...
je l'edite, je modifie un truc (tout bete, genre j'ajoute un commentaire //toto) , je sauve
je compile mon source->plus de warning
je l'edite, je modifie un truc (tout bete, je vire le commentaire //toto  :lol: ) , je sauve
je compile mon source->warning
je le fais tourner, pas de souci tout marche...
 
etc etc...
 
donc ca marche tout le temps et le warning n'apparait qu'une fois sur deux !
alors que je ne touche pas a l'edition aux structures mises en cause dans le warning !
 :pt1cable:  
 
mon warning :
monPrg.c:94: attention : affectation annule des qualificateurs du type du pointeur cible
monPrg.c:98: attention : affectation annule des qualificateurs du type du pointeur cible
 
qui correspondent a l'affectation du retour de ma fonction
 
Encore merci !

Reply

Marsh Posté le 10-01-2006 à 23:54:36    

fabrice91 a écrit :


Exemple :
je compile mon source->warning
je le fais tourner, pas de souci tout marche...
je l'edite, je modifie un truc (tout bete, genre j'ajoute un commentaire //toto) , je sauve
je compile mon source->plus de warning
je l'edite, je modifie un truc (tout bete, je vire le commentaire //toto  :lol: ) , je sauve
je compile mon source->warning
je le fais tourner, pas de souci tout marche...
 
etc etc...

j'en déduis que le commentaire //toto fait tout planter, et que commenter son code c'est mal [:klem3i1]  
 
Ne me remerciez pas, je sais que je suis génial :o

Reply

Marsh Posté le 11-01-2006 à 02:01:56    

fabrice91 a écrit :

bonsoir,
 
un petit souci :
j'ai déclaré une structure :
 
typedef struct _maStruct {
char i ;
char j ;
} maStruct ;
 
Ensuite je cree un tableau multidimensionnel de pointeurs de cette structure:
maStruct* tab[4][4] ;
 
je veux une fonction getStruct() qui me renvoie ce tableau multi.
 
Le typedef de la structure, la definition du tableau et la fonction getStruct() sont dans un module.c
Je veux appeller getStruct() a partir de mon main.c (grace a un include "module.h" )
j'ai un probleme pour le prototype de ma fonction getStruct !
je pensais faire dans module.c un :
 
maStruct* tab[4][4] ;
maStruct* getStruct() {
return tab[4][4] ;
}
 
et appellé par main.c comme ceci :
 
maStruct* toto[4][4] ;
toto[4][4] = getStruct() ;
 
mais il y a une incompatibilité de type...
quelqu'un aurait-il une idée ?
merci


Hum... toto[4][4] est hors limites !!!
 
Sinon, ta fonction "getStruct()" renvoyant l'adresse du premier élément d'un tableau en 2d de pointeurs sur "maStruct"... ta fonction renvoie un "maStruct ***"
 
Sinon, le simple fait que tu aies un warning folâtre prouve qu'il y a un truc que le compilo n'aime vraiment pas ce que t'as fait...


Message édité par Sve@r le 11-01-2006 à 02:03:53

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 11-01-2006 à 22:18:45    

fabrice91 a écrit :


Une fonction ne sait pas retourner un tableau. Elle peut éventuellement retourner l'adresse du premier élément du tableau. C'est assez compliqué et je conseille l'encapsulation dans une structure. Ca permet en plus de conserver la taille...


 
oui d'accord c'est bien l'adresse du premier element de mon tableau que je veux...
cette adresse n'est-elle pas alors tab[0][0] ?  
 
Et dans ton exemple ici :
 

fabrice91 a écrit :


struct mesdonnees
{
   maStruct* tab[4][4] ;
   size_t n;
};  
 
struct mesdonnees data;  
 


 
quel doit etre le prototype de ma fonction getStruct() ?
 
maStruct getStruct() {
return data.maStruct ;
}
 
???

Reply

Marsh Posté le 11-01-2006 à 22:43:21    

fabrice91 a écrit :

oui d'accord c'est bien l'adresse du premier element de mon tableau que je veux...
cette adresse n'est-elle pas alors tab[0][0] ?  
 
Et dans ton exemple ici :
 
 
 
quel doit etre le prototype de ma fonction getStruct() ?
 
maStruct getStruct() {
return data.maStruct ;
}
 
???


 
char tab[4] => quel et le type de "tab" ? => char *
char tab[4][4] => quel et le type de "tab" ? => char **
char *tab[4][4] => quel et le type de "tab" ? => char ***
maStruct* tab[4][4] => quel et le type de "tab" ? => maStruct ***
 
Maintenant tu dois avoir un sérieux soucis de conception parce que j'arrive pas à imaginer à quoi va te servir "getStruct()". Dès que t'as une variable "x" quelconque de type "struct mesdonnes"; t'as accès à "x.tab" de façon directe...


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 11-01-2006 à 23:02:22    

Sve@r a écrit :

char tab[4] => quel et le type de "tab" ? => char *
char tab[4][4] => quel et le type de "tab" ? => char **


Non.


int main(void)
{
   char tab[4][4];
 
   char **pa = tab; /* main.c:11: warning: initialization from incompatible pointer type */
   char (*pb)[4] = tab;
 
   return 0;
}


Merci de cesser de propager ce genre d'erreurs. Nous passons ensuite beaucoup de temps à recoller les morceaux.

Message cité 1 fois
Message édité par Emmanuel Delahaye le 11-01-2006 à 23:02:43

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 11-01-2006 à 23:09:34    

pour que svear comprenne son erreur, je dirais juste que tab[4][4] sera betement implementé derriere comme un tableau a une dimension, rien a voir donc avec un **

Reply

Marsh Posté le 15-01-2006 à 11:29:01    

Emmanuel Delahaye a écrit :

Non.


int main(void)
{
   char tab[4][4];
 
   char **pa = tab; /* main.c:11: warning: initialization from incompatible pointer type */
   char (*pb)[4] = tab;
 
   return 0;
}


Merci de cesser de propager ce genre d'erreurs. Nous passons ensuite beaucoup de temps à recoller les morceaux.


 
Oups... j'ai dit une grosse bêtise et en plus j'aurais dû m'en apercevoir tout seul. Désolé !!!


Message édité par Sve@r le 15-01-2006 à 12:38:12

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 15-01-2006 à 11:29:01   

Reply

Marsh Posté le 15-01-2006 à 12:12:37    

Je suis peut-être un peu à côté de la question, mais il me semble qu'en envoyant un tableau multidimensionnel à une fonction, le C travaille automatiquement avec des pointeurs sans que l'on ait à s'en soucier. Alors qu'on écrit le programme comme si on passait tout le tableau, il fait un passage par référence en envoyant l'addresse du premier élément.
 
Comme tout se fait par référence, il n'y a pas besoin de renvoyer quoi que ce soit. Le tableau de sortie est mis en argument.
 
Il faut juste préciser le nombre de colonnes. Par exemple :
 
Marquardt(nbp , deriv2 , deriv1 , deltap); // appel de la fonction
 
// fonction calculant les éléments du tableau deltap
int Marquardt(int nbp , double deriv2[][nbp+1] , double deriv1[] , double deltap[]) {
// blablabla
}

Message cité 1 fois
Message édité par jimipage le 15-01-2006 à 12:13:41

---------------
un perlien qui programme salement
Reply

Marsh Posté le 15-01-2006 à 12:22:50    

PS : Il fait également des passages par référence pour les tableaux à 1D


Message édité par jimipage le 15-01-2006 à 12:23:04

---------------
un perlien qui programme salement
Reply

Marsh Posté le 15-01-2006 à 12:24:58    

jimipage a écrit :

Je suis peut-être un peu à côté de la question,


Un peu.

Citation :


 mais il me semble qu'en envoyant un tableau multidimensionnel à une fonction, le C travaille automatiquement avec des pointeurs sans que l'on ait à s'en soucier. Alors qu'on écrit le programme comme si on passait tout le tableau, il fait un passage par référence en envoyant l'addresse du premier élément.


Certes, mais là, il n'était pas question de paramètres, mais du type retourné par une fonction. On ne sait pas retourner autre chose qu'une valeur (ici, une adresse). Si on veut l'adresse l'adresse du premier élément d'un tableau de int de 4 x 4, il faut ecrire :  

int (* f(void))[][4]


ou

int (* f(void))[4][4]


il était aussi question du type du pointeur cabable de stocker l'adresse du premier élément d'un tel tableau.

int (*pa)[4][4];


Citation :


Comme tout se fait par référence, il n'y a pas besoin de renvoyer quoi que ce soit. Le tableau de sortie est mis en argument.


Rien ne se fait par référence en C. Tout paramètre se transmet par valeur. Lorsque le paramètre est de type pointeur, la valeur transmise est une adresse.

Message cité 2 fois
Message édité par Emmanuel Delahaye le 15-01-2006 à 12:38:13

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 15-01-2006 à 12:51:51    

Emmanuel Delahaye a écrit :


Rien ne se fait par référence en C. Tout paramètre se transmet par valeur. Lorsque le paramètre est de type pointeur, la valeur transmise est une adresse.


 
C'est juste que le fait d'envoyer un tableau à une fonction revient à envoyer l'adresse du premier élément
 
Il me semblait juste que le problème était de renvoyer un type plus ou moins compliqué. En utilisant les pointeurs, est-il vraiment nécessaire de renvoyer quelque chose ?


---------------
un perlien qui programme salement
Reply

Marsh Posté le 15-01-2006 à 13:09:50    

jimipage a écrit :

Il me semblait juste que le problème était de renvoyer un type plus ou moins compliqué. En utilisant les pointeurs, est-il vraiment nécessaire de renvoyer quelque chose ?


C'est ce que demandait le posteur original (P.O.). La question de la conception de la fonction est un autre problème auquel seul le P.O. peut répondre.


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 15-01-2006 à 13:38:45    

Emmanuel Delahaye a écrit :


Rien ne se fait par référence en C. Tout paramètre se transmet par valeur. Lorsque le paramètre est de type pointeur, la valeur transmise est une adresse.


 
C'est vrai que j'aurais dû exprimer les choses autrement :
le tableau se transmet par valeur, cette valeur étant l'adresse du premier élément.
En tous cas, le résultat est que le tableau n'est pas copié, et on pointe directement sur les adresses des différents éléments. On peut finalement dire que les éléments du tableau sont transmis par référence, alors que le tableau est transmis par valeur (comme toujours en C)


---------------
un perlien qui programme salement
Reply

Marsh Posté le 15-01-2006 à 13:41:49    

jimipage a écrit :

On peut finalement dire que les éléments du tableau sont transmis par référence


Il n'y a pas de 'référence' en C.


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 15-01-2006 à 13:48:51    

Emmanuel Delahaye a écrit :

Il n'y a pas de 'référence' en C.


 
disons alors un passage par adresse


---------------
un perlien qui programme salement
Reply

Marsh Posté le 15-01-2006 à 14:11:32    

jimipage a écrit :

disons alors un passage par adresse


Non. "passage d'une adresse" ou "passage de l'adresse"...
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed