[C]Passer un tableau de structures en paramètres

Passer un tableau de structures en paramètres [C] - C - Programmation

Marsh Posté le 10-05-2007 à 23:12:34    

Salut à tous,
 
Voila j'ai un soucis pour passer un tableau de structure en paramètres voici mon code :
 
Tout d'abord la fonction :

Code :
  1. void init(t_lemmings lem[30])
  2. {
  3.   int j=0;
  4.   for(j=0;j<30;j++)
  5.   {
  6.       lem[j].posx=140;
  7.       lem[j].posy=100;
  8.       lem[j].depx=0;
  9.       lem[j].depy=0;
  10.       lem[j].mode=2;
  11.       lem[j].mvt=0;
  12.       lem[j].dir=0;
  13.       lem[j].cpt=25;
  14.   }
  15. }


 
Et l'appel :

Code :
  1. init(lem);


 
Avec ca mon programme plante, j'arrive pas à comprendre pourquoi...  :cry:  
 
En vous remerciant d'avance pour vos réponses,
 
Galaxed.

Reply

Marsh Posté le 10-05-2007 à 23:12:34   

Reply

Marsh Posté le 10-05-2007 à 23:48:29    

Tu serais pas à l'ECE toi ? :d
 
sinon je dirais a premiere vue  
 
 
void init(t_lemmings* lem) .

Reply

Marsh Posté le 10-05-2007 à 23:52:34    

ramseys a écrit :

Tu serais pas à l'ECE toi ? :d
 
sinon je dirais a premiere vue  
 
 
void init(t_lemmings* lem) .


 
Ca revient au même si je ne m'abuses

Reply

Marsh Posté le 11-05-2007 à 01:25:57    

ben non, dans l'exempe de ramseys, tu passes ton array "par référence" (un pointeur vers la structure en mémoire), ce qui permet de l'utiliser à partir de son adresse.
 
si mes souvenirs sont bons, on trouve ça dès les premiers chapitres ne n'importe quel bouquin sur le C.
 
avec des langages plus évolués, ça se fait de façon automatique (types de valeur vs types de référence)
 
attention : dans ce cas, tu travailles avec le tableau original et non une copie locale, donc toute modificétion apportée dans ta fonction sera visible depuis l'ensemble du programme.

Message cité 1 fois
Message édité par MagicBuzz le 11-05-2007 à 01:26:52
Reply

Marsh Posté le 11-05-2007 à 01:34:47    

galaxed a écrit :

Salut à tous,
 
Voila j'ai un soucis pour passer un tableau de structure en paramètres voici mon code :
 
Tout d'abord la fonction :

Code :
  1. void init(t_lemmings lem[30])
  2. {
  3.   int j=0;
  4.   for(j=0;j<30;j++)
  5.   {
  6.       lem[j].posx=140;
  7.       lem[j].posy=100;
  8.       lem[j].depx=0;
  9.       lem[j].depy=0;
  10.       lem[j].mode=2;
  11.       lem[j].mvt=0;
  12.       lem[j].dir=0;
  13.       lem[j].cpt=25;
  14.   }
  15. }


 
Et l'appel :

Code :
  1. init(lem);


 
Avec ca mon programme plante, j'arrive pas à comprendre pourquoi...  :cry:  
 
En vous remerciant d'avance pour vos réponses,
 
Galaxed.


 
avec un tableau de N éléments, on boucle de 0 à N-1

Reply

Marsh Posté le 11-05-2007 à 01:36:04    

donc idéalement transformer en:
 
void init( t_lemmings *lem, int size );
ou  
void init( t_lemmings lem[], int size );
 
tu peux aussi te faire des:
 
void copy_lemming( t_lemmings *dest, t_lemmings *src );
void copy_lemmings( t_lemmings *tab, unsigned int size, t_lemmings *src)
{
    while( size )
    {
        copy_lemming( tab, src );
       ++tab;
       --size;
    }  
}
 
pour initialiser, tu te fais un:
 
t_lemmings lem_std;
lem_std.machin=....
....
 
t_lemmings lasmala[30];
 
copy_lemmings( lasmala, 30, lem_std );


Message édité par bjone le 11-05-2007 à 01:41:15
Reply

Marsh Posté le 11-05-2007 à 06:45:31    

MagicBuzz a écrit :

ben non, dans l'exempe de ramseys, tu passes ton array "par référence" (un pointeur vers la structure en mémoire), ce qui permet de l'utiliser à partir de son adresse.
 
si mes souvenirs sont bons, on trouve ça dès les premiers chapitres ne n'importe quel bouquin sur le C.
 
avec des langages plus évolués, ça se fait de façon automatique (types de valeur vs types de référence)
 
attention : dans ce cas, tu travailles avec le tableau original et non une copie locale, donc toute modificétion apportée dans ta fonction sera visible depuis l'ensemble du programme.


 
Au temp pour moi, la fonction etant :
 

Code :
  1. void(init(t_lemmings lem[])


 et non pas init(t_lemmings lem[30]) comme écrit plus tot

Reply

Marsh Posté le 11-05-2007 à 08:23:26    

ah oui effectivement.
c'est chelou par contre que tu puisses passer un array par valeur...
moi j'éviterais hein, tu bouffes de la mémoire pour rien là

Reply

Marsh Posté le 11-05-2007 à 09:29:01    

quand tu passe un array par valeur tu passe que la valeur de l'adresse du premir élément du tableau de toute facon, non ?

Reply

Marsh Posté le 11-05-2007 à 09:38:04    

Il n'y a que du passage par valeur en C les gars ... sauf que les tableaux ne sont pas copiables/lvalue/etc, mais ont la propriété que T t[N], t peutêtre converti implicitement en T* de valeur &t[0]

Reply

Marsh Posté le 11-05-2007 à 09:38:04   

Reply

Marsh Posté le 11-05-2007 à 10:05:39    

ok
 
sinon, quand je parle de "passage par référence", c'est justement ça que je veux dire ;). je suis d'ailleurs étonné que le C fasse cette conversion implicitement (ce qui correspond donc rigoureusement à un type référence, qui n'est pas censé exister en C).
je pensais qu'on devait manuellement passer la référence (pointeur) plutôt que la valeur (convertie implicitement en référence, comme dans les langages de haut niveau qui font la différence entre types valeur et types référence). je ne pensais même pas que ça compilerait sinon.


Message édité par MagicBuzz le 11-05-2007 à 10:06:45
Reply

Marsh Posté le 11-05-2007 à 10:10:48    

MagicBuzz a écrit :

sinon, quand je parle de "passage par référence", c'est justement ça que je veux dire ;). je suis d'ailleurs étonné que le C fasse cette conversion implicitement (ce qui correspond donc rigoureusement à un type référence, qui n'est pas censé exister en C).


Même pas.
passage par référence != passage par pointeur

 

Y a pas de référence en C. Et le passage par pointeur oblige à déréférencer ce pointeur pour accéder aux données, et puis au final c'est juste un bête passage par copie de l'adresse d'une zone mémoire.

 


Passage par pointeur :
void blabla (int *a)
{
   *a = 42;
}

 

Passage par référence (C++) :
void blabla(int &a)
{
   a = 42;
}


Message édité par Elmoricq le 11-05-2007 à 10:11:31
Reply

Marsh Posté le 11-05-2007 à 10:31:18    

Je dois avoir le vocable pollué par le C# et toi par le C/C++, tu dis la même chose que moi j'ai l'impression :spamafote:
 
Si tu as le droit d'écrire ça en C :
 

Code :
  1. void init( t_lemmings lem[], int size );
  2.  
  3. init(monArray, monArraySize);


 
Alors je ne vois pas de différence par rapport au comportement d'un Array en C# (type référence), passé par valeur à une fonction (c'est à dire pointeur passé par valeur, mais pas les données elles-mêmes)
 

Citation :


Une variable de type référence ne contient pas directement les données, mais contient une référence aux données. Lorsque vous passez un paramètre de type référence par valeur, il est possible de modifier les données sur lesquelles pointe la référence, comme par exemple la valeur d'un membre de classe. Toutefois, vous ne pouvez pas modifier la valeur de la référence elle-même. Cela signifie que vous ne pouvez pas utiliser la même référence pour allouer de la mémoire pour une nouvelle classe et la faire persister en dehors du bloc. Pour cela, passez le paramètre en utilisant le mot clé ref ou out. Par souci de simplicité, les exemples qui suivent utilisent ref.


http://msdn2.microsoft.com/fr-fr/l [...] s.80).aspx
 
"ref" correspond à une façon sexy de passer un pointeur sur le pointeur.
 
 
 
PS : Si effectivement, ça n'a rien à voir, je vais peut-être enfin comprendre pourquoi j'ai jamais rien compris au C :D

Message cité 1 fois
Message édité par MagicBuzz le 11-05-2007 à 10:55:32
Reply

Marsh Posté le 11-05-2007 à 11:04:42    

MagicBuzz a écrit :

Je dois avoir le vocable pollué par le C# et toi par le C/C++, tu dis la même chose que moi j'ai l'impression :spamafote:
 
Si tu as le droit d'écrire ça en C :
 

Code :
  1. void init( t_lemmings lem[], int size );
  2.  
  3. init(monArray, monArraySize);


 
Alors je ne vois pas de différence par rapport au comportement d'un Array en C# (type référence), passé par valeur à une fonction (c'est à dire pointeur passé par valeur, mais pas les données elles-mêmes)


mais tu nous saoules avec tes références C#, c'est complètement hors sujet.  
Et bel contradiction sur le passage par valeur.
Ici la syntaxe [] c'est la __même_chose__ qu'une *.

Reply

Marsh Posté le 11-05-2007 à 11:37:20    

Ici la syntaxe [] c'est la __même_chose__ qu'une *.
 
=> c'est quoi la différence avec un autre langage ?
un array a toujours été ni plus ni moins qu'une adresse mémoire. et le [] n'est qu'une façon simple de gérer l'indexation à partir de la taille du type de base du array plutôt que de se faire chier à la gérer à la main à grands coups de address + sizeof(basetype) * index
 
Ceci est tout aussi vrai en C qu'en Java ou en Ruby. Quand il s'agit d'un langage évolué permettant une représentation physique d'un array de façon non contigüe en mémoire, c'est de toute façon le travail du CLR (ou autre) de dématérialiser cette réprésentation pour ne laisser visible au programme qu'une partie contigüe. Le fonctionnement reste donc toujours le même.
 
Arrête de m'insulter, et pour une fois, explique vin dieu.
J'ai le droit de pas piger, t'as le droit de piger, mais t'as aussi surtout le devoir d'expliquer à ceux qui pigent pas. Je te rappelle que t'es sur un forum d'entre-aide, pas devant un jury d'un concours.

Message cité 1 fois
Message édité par MagicBuzz le 11-05-2007 à 11:41:04
Reply

Marsh Posté le 11-05-2007 à 11:52:16    

MagicBuzz a écrit :

Ici la syntaxe [] c'est la __même_chose__ qu'une *.
 
=> c'est quoi la différence avec un autre langage ?
un array a toujours été ni plus ni moins qu'une adresse mémoire. et le [] n'est qu'une façon simple de gérer l'indexation à partir de la taille du type de base du array plutôt que de se faire chier à la gérer à la main à grands coups de address + sizeof(basetype) * index


Bah non. Apprends le C. Un tableau n'est pas une adresse mémoire. Je parlais de void foo(int *x) sémantiquement égal à void foo(int x[]). La deuxieme notation connote juste une sémantique usage différent. Mais c'est la même chose, donc l'usage est le même de toutes façons ...
 

MagicBuzz a écrit :


Ceci est tout aussi vrai en C qu'en Java ou en Ruby. Quand il s'agit d'un langage évolué permettant une représentation physique d'un array de façon non contigüe en mémoire, c'est de toute façon le travail du CLR (ou autre) de dématérialiser cette réprésentation pour ne laisser visible au programme qu'une partie contigüe. Le fonctionnement reste donc toujours le même.

bah non. La tu compares un langage avec passage par valeur avec des langages ou passage par référence (sauf primitif en java). Personne ne parle d'implémentation ici. On parle type et sémantique. Le C c'est du passage par valeur.

Reply

Marsh Posté le 11-05-2007 à 11:58:09    

bjone a écrit :

avec un tableau de N éléments, on boucle de 0 à N-1


 
Je te remercie mais je vais bien de 0 a 29

Reply

Marsh Posté le 11-05-2007 à 12:28:25    

MagicBuzz tu vas encore m'en vouloir mais franchement, arrête de poster dans cette catégorie. Ou alors pose des questions, mais ne répond pas alors qu'il y a manifestement beaucoup de principes fondamentaux qui t'échappent en C. Moi tu vois, même si je connais bien le C, je ne connais pas tout en C. Quand je ne sais pas, ou quand je ne suis pas sûr de moi, je m'abstiens de répondre ou je dis clairement que j'ai un doute. Toi tu affirmes des choses fausses avec une assurance qui est dangereuse pour les novices.

Reply

Marsh Posté le 11-05-2007 à 13:25:48    

galaxed a écrit :

Salut à tous,
 
Voila j'ai un soucis pour passer un tableau de structure en paramètres voici mon code :
 
 
Et l'appel :

Code :
  1. init(lem);


 
 
Galaxed.


Si on reprend depuis le début ... quelle est la déclaration de lem ?

Reply

Marsh Posté le 11-05-2007 à 13:26:23    

galaxed a écrit :

Je te remercie mais je vais bien de 0 a 29


:lol: exact, faut pas poster de correction à 1h30 du mat :D
 
bon alors, montre l'appel c'est que ton tableau/bloc mémoire est à l'ouest avant l'appel.
 
(grilled par taz :D)


Message édité par bjone le 11-05-2007 à 13:26:51
Reply

Marsh Posté le 11-05-2007 à 13:38:20    

:p
 

Code :
  1. typedef  struct lemmings
  2. {
  3.     int numero;
  4.     int posx;
  5.     int posy;
  6.     int depx;
  7.     int depy;
  8.     int mode;
  9.     int mvt;
  10.     int dir;
  11.     int cpt;
  12. }t_lemmings;


 

Code :
  1. t_lemmings lem[30];


 
l'appel c'est :

Code :
  1. init(lem);


 
et la fonction :

Code :
  1. void init(t_lemmings lem[])
  2. {
  3.   int j=0;
  4.   for(j=0;j<30;j++)
  5.   {
  6.       lem[j].posx=140;
  7.       lem[j].posy=100;
  8.       lem[j].depx=0;
  9.       lem[j].depy=0;
  10.       lem[j].mode=2;
  11.       lem[j].mvt=0;
  12.       lem[j].dir=0;
  13.       lem[j].cpt=25;
  14.   }
  15. }


 
Et donc avec ca, je plante des que j'utilise une des structures dans le main().


Message édité par galaxed le 11-05-2007 à 13:41:06
Reply

Marsh Posté le 11-05-2007 à 13:39:20    

nan ça ok, mais lem, c'est quoi au juste ? [:dawak]

 

edit : le fourbe, il a édité après mon message [:dawa]


Message édité par Elmoricq le 11-05-2007 à 13:57:02
Reply

Marsh Posté le 11-05-2007 à 13:52:54    

c'est la suite qui foire.

Reply

Marsh Posté le 11-05-2007 à 13:57:59    

lem c'est ça [:cerveau foudtag]

Reply

Marsh Posté le 11-05-2007 à 14:43:17    

Le programme fonctionne si j'initialise les valeurs des structures dans le main. Donc le probleme vient bien du passage en parametres.

Reply

Marsh Posté le 11-05-2007 à 15:10:53    

bon donne ton programme complet ou apprend à te servir d'un debugguer. init(lem) est OK

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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