bonjour tout le monde,
j'ai quelques problèmes pour bien saisir les structures de données en C, à quoi peuvent servir les champs de bits exactement??les unions??
merci de m'aider je débute en C et je compte bien y aller doucement mais surement
merci
bonjour tout le monde,
j'ai quelques problèmes pour bien saisir les structures de données en C, à quoi peuvent servir les champs de bits exactement??les unions??
merci de m'aider je débute en C et je compte bien y aller doucement mais surement
merci
Salut, bienvenue sur le forum. Je ne vais pas pouvoir t'aider car je ne connais pas la réponse précise à tes questions. En revanche, pour les unions, j'ai lu à plusieurs reprises que c'est à éviter.
N'as-tu rien trouvé sur google ou sur la Faq C ?
Les unions permettent à plusieurs structure de partager la même zone mémoire.
Ceci peut être utile si:
- l'on n'a pas beaucoup de mémoire.
- l'on désire gérer sa structure en tant que buffer (afin de l'envoyer vers un fichier ou un périphérique). Dans ce cas on peut faire une union entre une structure et un tableau d'octet.
- ...
Si tu ne vis pas ce que tu penses alors tu penses ce que tu vis.
Les champs de bit dans une structure sont le « seul » moyen de descendre en dessous du niveau de l'octet et de contrôler exactement, au bit près, la taille des champs de ta structure. Les champs de bits te permettent alors de « partitionner » l'intérieur d'un de tes membres. Par exemple, un « unsigned int » fait généralement 32 bits, soit 4 octets, sur les machines actuelles (32 bits elles aussi). Donc :
Code C : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 struct _bit { unsigned int a : 3; unsigned int b : 5; unsigned int c : 24; };
La structure ci-dessus contient exactement un seul « unsigned int », et mesure donc 4 octets. Cependant, le champ « a » ne concerne que les bits 0 à 2 de cet entier, le champ « b » les bit 3 à 7, et « c » les bits 8 à 31 (donc tous les autres).
Il arrive fréquemment qu'une variable de type « entier non signé » serve en fait à recevoir des flags. Dans ce cas, l'approche la plus courante consiste à manipuler cette variable avec des symboles #define et des opérations logiques. Le faire avec les champs de bits te permet de manipuler ces flags directement et individuellement, sans gérer la logique toi-même. Ça devient surtout intéressant quand ces champs font plus d'un bit de large et que leur valeur a une signification arithmétique : tu n'es plus obligé de d'isoler les bits toi-même et de les ramener à la main vers la droite.
En ce qui concerne les unions, ce n'est pas du tout un modèle à proscrire, bien au contraire. Il s'agit d'un modèle qui se comporte exactement comme une structure, mais dont tous les membres occupent la même position mémoire. Ça veut donc dire que tu ne peux utiliser qu'un seul membre à la fois (puisque son contenu écrase celui des autres) mais également que la taille de l'union se résume à celle du membre le plus grand.
C'est extrêmement utile lorsque tu dois transmettre des informations dont le type peut être variable. Par exemple, on peut imaginer une fonction qui, selon les cas, te renvoie soit un entier, soit une chaîne de caractère. Tu ne peux pas déclarer une fonction qui soit des deux types à la fois. Par contre, elle peut être du type de ton union.
Ça devient franchement utile lorsque tu as non pas, quatre ou cinq, mais des centaines de champs, ou lorsque ces champs sont eux-mêmes des structures. Le système X-Window (le système d'interface graphique des unixoïdes) utilise comme beaucoup d'autres, un système d'événements, chaque événement étant un message envoyé à qui veut l'entendre lorsque qu'il se passe quelque chose, tel qu'un mouvement de souris, un clic, la fermeture d'une fenêtre, etc.
Chaque événement est une structure qui contient toutes les informations le concernant (par exemple, dans le cas d'un clic, tu auras le numéro du bouton et les coordonnées de la zone cliquée). Naturellement, chaque structure est propre à l'événement qu'elle décrit.
On comprend alors qu'une fonction doit être capable de lire, d'émettre ou de recevoir en argument n'importe quel type d'événement. On comprend également qu'une « structure de structure » formerait un type immense et majoritairement vide. La solution la plus naturelle est donc l'union, puisque chaque événement n'est que d'un seul type à la fois :
Code C : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 /* The XEvent structure is a union of the individual structures declared for each event type : */ typedef union _XEvent { int type; /* must not be changed */ XAnyEvent xany; XKeyEvent xkey; XButtonEvent xbutton; XMotionEvent xmotion; XCrossingEvent xcrossing; XFocusChangeEvent xfocus; XExposeEvent xexpose; XGraphicsExposeEvent xgraphicsexpose; XNoExposeEvent xnoexpose; XVisibilityEvent xvisibility; XCreateWindowEvent xcreatewindow; XDestroyWindowEvent xdestroywindow; XUnmapEvent xunmap; XMapEvent xmap; XMapRequestEvent xmaprequest; XReparentEvent xreparent; XConfigureEvent xconfigure; XGravityEvent xgravity; XResizeRequestEvent xresizerequest; XConfigureRequestEvent xconfigurerequest; XCirculateEvent xcirculate; XCirculateRequestEvent xcirculaterequest; XPropertyEvent xproperty; XSelectionClearEvent xselectionclear; XSelectionRequestEvent xselectionrequest; XSelectionEvent xselection; XColormapEvent xcolormap; XClientMessageEvent xclient; XMappingEvent xmapping; XErrorEvent xerror; XKeymapEvent xkeymap; long pad[24]; } XEvent;
Les différentes structures, individuellement, ont une taille qui peut aller de 20 octets (pour XAnyEvent ou XErrorEvent) à 68 octets (pour XCrossingEvent). On voit aussi que le champ « pad » sert à réserver de la place et à garantir une taille fixe. L'union XEvent fait donc 96 octets de long, alors qu'une structure de structure en ferait 1176 : douze fois plus gros !
Mais une union n'a pas qu'un rôle économique : il est surtout sémantique. Une structure sert à définir un type composite, formé de chacun de ses membres. Une union sert à définir l'instance d'une variable dont le type peut être un de ceux listés dans l'union.
Le problème des champs de bits, c'est qu'ils ne sont pas portables: La norme ne définit pas comment les champs sont effectivement organisés, tu ne peux donc pas t'en servir pour faire un pilote "universel" pour un certain matériel (par exemple, un pilote pour interface RS232 qui marcherait n'importe où).
Pour ce genre de choses, les décalages de bits marchent mieux.
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.
"Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
Apparently everyone. -- Raymond Chen.
Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.
Mac LAK.
___________________________________________________
Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.
Sources et composants Delphi sur mon site, L'antre du Lak.
Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.
Rejoignez-nous sur : ► Serveur de fichiers [NAS] ► Le Tableau de bord projets ► Le groupe de travail ICMO
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager