[C] acces aux champs d une structure

acces aux champs d une structure [C] - Programmation

Marsh Posté le 22-05-2001 à 15:11:21    

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);
}

Reply

Marsh Posté le 22-05-2001 à 15:11:21   

Reply

Marsh Posté le 22-05-2001 à 15:20:25    

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...

Reply

Marsh Posté le 22-05-2001 à 15:27:49    

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 ...

Reply

Marsh Posté le 22-05-2001 à 15:39:52    

le but est de parcourir tout les champs de ma structure
avec une boucle  
voila

Reply

Marsh Posté le 22-05-2001 à 15:41:04    

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;
}


---------------
Je ne suis ni pour, ni contre, bien au contraire  
Reply

Marsh Posté le 22-05-2001 à 15:43:22    

Salut theetete


---------------
La bave du crapaud n'empèche pas la caravane de passer .
Reply

Marsh Posté le 22-05-2001 à 15:44:14    

Salut,
le pb c'est que le compilateur peut réarranger les champs il me semble

Reply

Marsh Posté le 22-05-2001 à 15:44:51    

lord ii a écrit a écrit :

Salut theetete




coucou ca fait un bout de tps

Reply

Marsh Posté le 22-05-2001 à 15:46:20    

6 mois presque. mais c'est toujours aussi tranquille le parametrage...


---------------
La bave du crapaud n'empèche pas la caravane de passer .
Reply

Marsh Posté le 22-05-2001 à 15:51:53    

[#000ef0]alors koi de neuf sur le toobot ?

Reply

Marsh Posté le 22-05-2001 à 15:51:53   

Reply

Marsh Posté le 22-05-2001 à 15:55:47    

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

Reply

Marsh Posté le 22-05-2001 à 15:58:38    

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 ?

Reply

Marsh Posté le 22-05-2001 à 16:04:56    

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

Reply

Marsh Posté le 22-05-2001 à 16:09:55    

ouais mais si ca s utilise comme une structure on revient
au debut du probleme

Reply

Marsh Posté le 22-05-2001 à 16:10:17    

mets tout simplement un tableau dans ta structure
pour tous les champs integer, un tableau de char *....


---------------
Je ne suis ni pour, ni contre, bien au contraire  
Reply

Marsh Posté le 22-05-2001 à 16:11:45    

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 ?

Reply

Marsh Posté le 22-05-2001 à 16:26:27    

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

Reply

Marsh Posté le 22-05-2001 à 16:36:38    

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 ?

Reply

Marsh Posté le 22-05-2001 à 16:36:44    

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]

Reply

Marsh Posté le 22-05-2001 à 19:44:38    

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+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 22-05-2001 à 19:48:11    

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+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 22-05-2001 à 22:26:24    

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.

Reply

Marsh Posté le 22-05-2001 à 22:48:29    

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 ...

Reply

Marsh Posté le 22-05-2001 à 23:09:40    

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.

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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