Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1036 connectés 

 


Dernière réponse
Sujet : [C] acces aux champs d une structure
BifaceMcLeOD

gilou a écrit a écrit :

Un struct, c'est a priori fait pour regrouper des donnees heterogenes. De ce fait il n'y a pas de methode generale pour parcourir tous les champs d'un struct un par un.




Si ça existe, ça s'appelle la "reflection" en anglais. Etre capable d'interroger la structure d'une structure. Mais c'est un concept typiquement objet, en C, c'est donc impossible.
 
gilou> Les unions en C sont crades et dangereuses parce que tu ne sais jamais a priori quel est le bon champ à utiliser. En Pascal (et aussi Ada d'ailleurs), l'équivalent existe (record case), mais il est conditionné à un champ sélecteur (exemple en Ada, syntaxe de mémoire) :

Code :
  1. type Personne is
  2.     record
  3.        nom    : string (1 .. 256);
  4.        prenom : string (1 .. 256);
  5.        case sexe : boolean is
  6.            when true  =>
  7.               barbe : boolean;
  8.            when false =>
  9.               nom_jeune_fille : string (1 .. 256);
  10.        end case;
  11.     end record;


Ici, il devient interdit (par le compilateur) d'accéder à "barbe" si "sexe" vaut "false". En C, on peut faire la même chose, il faut le simuler.


Votre réponse
Nom d'utilisateur    Pour poster, vous devez être inscrit sur ce forum .... si ce n'est pas le cas, cliquez ici !
Le ton de votre message                        
                       
Votre réponse


[b][i][u][strike][spoiler][fixed][cpp][url][email][img][*]   
 
   [quote]
 

Options

 
Vous avez perdu votre mot de passe ?


Vue Rapide de la discussion
BifaceMcLeOD

gilou a écrit a écrit :

Un struct, c'est a priori fait pour regrouper des donnees heterogenes. De ce fait il n'y a pas de methode generale pour parcourir tous les champs d'un struct un par un.




Si ça existe, ça s'appelle la "reflection" en anglais. Etre capable d'interroger la structure d'une structure. Mais c'est un concept typiquement objet, en C, c'est donc impossible.
 
gilou> Les unions en C sont crades et dangereuses parce que tu ne sais jamais a priori quel est le bon champ à utiliser. En Pascal (et aussi Ada d'ailleurs), l'équivalent existe (record case), mais il est conditionné à un champ sélecteur (exemple en Ada, syntaxe de mémoire) :

Code :
  1. type Personne is
  2.     record
  3.        nom    : string (1 .. 256);
  4.        prenom : string (1 .. 256);
  5.        case sexe : boolean is
  6.            when true  =>
  7.               barbe : boolean;
  8.            when false =>
  9.               nom_jeune_fille : string (1 .. 256);
  10.        end case;
  11.     end record;


Ici, il devient interdit (par le compilateur) d'accéder à "barbe" si "sexe" vaut "false". En C, on peut faire la même chose, il faut le simuler.

zop toujours à la recherche de la solution du 'moindre effort' theetete, tsss, tsss ...
Le Toobot va mal, de plus en plus de bugs découverts, aucune correction apportée, il prend l'eau de toutes parts (comme nous), d'ailleurs, on s'est fait déménager à l'intérieur, je suis dorénavent très mal situé, mais bon ...
philou_a7 gilou a raison : rien ne garantit que les champs vont etre stockés de manière contigüe, sauf a trouver une option de compilation qui va bien....
 
La solution de BENB avec l'union (struct + int*) elle celle qui doit le mieux marcher, mais rien ne t'assure que l'ordre de champs est respecté.
 
Mais je continue à dire que ce que tu veux faire est une horreur ! Tu veux afficher toute une structure, tu te tapes tout à la main, point barre. Sinon, fallait tout stocker dans un tableau et l'indexer par une enum pour nommer les elements de ce tableau.
gilou

tgrx a écrit a écrit :

Type s;
int* ptr= (int*) &s;
 
for (int i=0; i<20; i++)
  printf("%d\n", *ptr++);
 
Ca marche, mais c'est une maniere de programmer DEGUEULASSE.
Et en plus, si tu changes ta structure par la suite, tu devras retoucher toutes tes routines qui accedent de maniere sale...
 
bref... PAS BIEN :D
 
 




 
Ca marche pas toujours, puisque le compilo peut a priori reordonner les membres, ou les stocker danws des zones non jointives s'il le veut.
Dans ce cas precis, il y a pas trop de raison qu'il le fasse, mais a priori, rien ne garantit que ta methode marche.
A+,

gilou Un struct, c'est a priori fait pour regrouper des donnees heterogenes. De ce fait il n'y a pas de methode generale pour parcourir tous les champs d'un struct un par un.
Si tu veux grouper des donnees homogenes, tu utilises un tableau.
 
>1- l'union est une horreur du C  
>2- les membres d'une union sont places au meme endroit en memoire  
>3- ca s'utilise comme une structure  
 
1. ca a jamais ete une horreur, ca s'utilise tres facilement.
2. normal puisque il n'y a qu'un seul membre de stocke. C'est donc pas "au meme endroit".
3. la syntaxe est similaire.
 
Autant que je me souvienne, le meme type de donnee existe aussi en pascal; c'est pas reserve au C les unions.
A+,
tgrx Type s;
int* ptr= (int*) &s;
 
for (int i=0; i<20; i++)
  printf("%d\n", *ptr++);
 
Ca marche, mais c'est une maniere de programmer DEGUEULASSE.
Et en plus, si tu changes ta structure par la suite, tu devras retoucher toutes tes routines qui accedent de maniere sale...
 
bref... PAS BIEN :D

 

[edit]--Message édité par tgrx--[/edit]

BENB tu fais une union entre un structure et un tableau de vingt elements et comme ca tu accede soit par la structure, soit par le tableau
 
union toto
{
struct titi;
int *tab[20];
}
 
union toto toto;
toto.tab[i]=....
 
...
 
 
...
 
toto.titi.a =  
 
etc...
 
c'est bien ca qu'il te faut
 
maintenant la partie structure est-elle bien utile ?
un tableau + un enum nomment les element ne suffit pas ?
theetete imagine une structure  avec 20 champs de type int qui s appelle a, b, c ...
donc pour acceder a tous les champs chui obliger de tous les taper a la main struct.a struct.b ...
donc pour me simplifier la vie je voudrais faire une boucle
du genre for(i = 0; i < 20; i++){
printf(struct.i); // c est n importe koi la  
} mais voila le but
donc ca doit etre faisable avec du casting, bidouille sur les
adresse en memoire car normalement les 20 int sont contiguent ds
la memoire
philou_a7 Non, avec l'union (qui n'est pas forcement une horreur, y a des cas ou c'est bien pratique) tous ses champs vont etre stockés au même endroit dans la memoire.
 
Franchement, a mon avis, le truc que tu cherche n'est pas possible. D'ailleurs, perso, j'en vois pas l'interet ! tu pourrais expliquer ?
jupiler mets tout simplement un tableau dans ta structure
pour tous les champs integer, un tableau de char *....
theetete ouais mais si ca s utilise comme une structure on revient
au debut du probleme
BENB 1- l'union est une horreur du C
2- les membres d'une union sont places au meme endroit en memoire
3- ca s'utilise comme une structure
4- c'est a TES risques et perils
theetete

BENB a écrit a écrit :

Dans ce cas il y a l'horreur supreme :
union toto{
struct ... ;
int tab[3];
};
?




 
euh ?
 
et ca s utilise comment ton union ?

BENB Dans ce cas il y a l'horreur supreme :
union toto{
struct ... ;
int tab[3];
};
?
theetete [#000ef0]alors koi de neuf sur le toobot ?
Lord II 6 mois presque. mais c'est toujours aussi tranquille le parametrage...
theetete

lord ii a écrit a écrit :

Salut theetete




coucou ca fait un bout de tps

zop Salut,
le pb c'est que le compilateur peut réarranger les champs il me semble
Lord II Salut theetete
jupiler ben c'est pas possible
 
tu peux pas affecter ou lire un élément d'une structure
sans le nommer.  
 
ou alors tu fais une fonction :
 
int getTata(s_test st)
{
    return st.tata;
}
theetete le but est de parcourir tout les champs de ma structure
avec une boucle  
voila
theetete euh non en fait je voudrais qu a aucun
moment du code je n ai besoin de taper "tata"
donc des calculs sur les adresses ...
BENB C'est louche...
 1- int *ptr = &(test.tata);
 
 2- int off7= offset(struct s_test,tata) je crois recherche l'aide
    *(&test+off7) =...
 
a utiliser avec Parcimoni, voir pas tu tout...
theetete je voudrais pouvoir modifier un champ d une structure sans
connaitre/specifier le nom du champs en question.
 
struct s_test{
  int   toto;
  int   tata;
  int   titi;
};
 
int     main()
{
  struct s_test test;
 
  //test.tata = 66; faire l equivalent de cette ligne sans le '.'
  printf("%i\n", test.tata);
}

Copyright © 1997-2025 Groupe LDLC (Signaler un contenu illicite / Données personnelles)