|
L'équipe progG de Ti-Fr
|
Voici les nicks de vos serviteurs ;-)
chickensaver_john
Kevin Kofler
Thibaut
janjan2
TiMad
Iceman89
fréka
Zewoo
Squale92
Verstand
ZdRUbAl
UtOpIaH
et nEUrOne ...
|
|
Une idée ?
|
Une idée pour améliorez cette partie?
ou tout simplement vous souhaitez participer à l'élaborations
des tutos.
Mailez-nous ici
|
| |
Chapitre
XXII
Dans ce chapitre, nous allons nous intéresser à trois
des moyens que nous propose le C pour grouper des données sous un même
nom : nous verrons en premier lieu les structures, puis les unions, pour finir
par les champs de bits.
I:\
Les Structures :
Les structures constituent le moyen de regrouper plusieurs
variables de plusieurs types différents sous un même nom, et ce de la façon
la plus efficace qui soit..
Nous allons en premier partir d'un exemple simple, qui est
celui qui est souvent repris lorsqu'il s'agit de s'initier aux structures : nous
allons commencer par étudier la définition géométrique d'un point, dans un
repère en deux dimensions.
Ce point sera désigné par une variable X, qui aura
pour valeur l'abscisse du point, et une variable Y, qui aura pour valeur
l'ordonnée du point. Ici, pour simplifier, nous considérerons que ces deux
valeurs sont entières, et qu'elles appartiennent à l'intervalle [-35768 ;
35767], c'est-à-dire qu'elles pourront être codées sur 16 bits, par un short.
Pour définir une structure permettant de définir des
données de type POINT, contenant deux shorts,
nommés X et Y, il faut utiliser ceci :
struct POINT
{
short
X;
short Y;
};
A présent, il est
possible de définir un point, que nous noterons A, en effectuant l'opération
suivante :
struct
POINT A;
De la sorte, le point A constitue un regroupement de
deux variables, qui sont celles comprises dans la structure POINT. Maintenant,
pour fixer l'abscisse de A à 10, et son ordonnées à 15, il convient
d'utiliser ceci :
A.X = 10;
// Affecte 10 au champ X de la structure A de
type POINT.
A.Y
= 15;
//
Affecte 15 au champ Y de la structure A de type POINT.
Comme vous pouvez ici le constater, les
structures que nous avons ici défini comme étant de type POINT permettent de
regrouper plusieurs données (en l'occurrence, deux shorts)
qui permettent d'obtenir des définitions moins lourdes, et plus précises,
puisque nous n'utilisons qu'une seule variable (composée de deux
"sous-variables") pour définir chaque point...
En effet, il est nettement plus simple de n'utiliser qu'une
seul variable pour définir un unique point, que deux !
Dans la doc de TIGCC, il n'est pas rare de rencontrer ce
genre d'écriture : typedef
struct... Pour vous montrer à quoi correspond ce type de
définition, nous allons réécrire le même exemple, mais de façon différente
(le résultat sera naturellement équivalent !)
typedef sruct
{
short
X;
short
Y;
} POINT;
Cette définition revient au même que celle que nous
avions utilisé précédemment, mais, par la suite, pour définir des points
correspondant à ce type de structure, il nous suffirait de faire ceci :
POINT A; // au lieu de struct POINT
A; comme nous le faisions auparavant...
En effet, l'utilisation de typedef
dans la définition de la structure permet d'assimiler le type de structure
définit, au nom donné en fin de déclaration
Nous verrons dans la quatrième partie de ce site un exemple plus complet de
manipulation de structure...
II:\
Les champs de Bits :
En C, il est possible de regrouper plusieurs
données ensemble, de la même façon qu'avec les structures, mais en ne
conservant que deux états pour ces données : 1 ou 0 (VRAI ou FAUX, ACTIF ou
NON_ACTIF, ...).
Il s'agira ici de définir ce qui est nommé "champs de
bits". Il serait bien entendu possible d'utiliser dans ce but des
structures composées de plusieurs variables de type short,
mais ce serait gaspiller de l'espace mémoire, puisque nous n'utiliserions alors
qu'un seul de chacun des 16 bits de chaque short.
Ici, nous utiliserons des unsigned
short, qui nous permettront de grouper de nombreux bits dans une
seule variable...
Voici comment il convient de définir ce type de données :
struct
champ_de_bits
{
unsigned short bit1:1, bit2:1,
bit3:1; // A ma connaissance, vous
pouvez définir jusqu'à 8 bits à l'intérieur d'un champ de bits basé sur un
unsigned short... (du moins, c'est le maximum que j'ai trouvé dans TIGCC !)
};
Ici, chaque variable de type unsigned
short déclarée est suivie de ":1",
ce qui signifie qu'on ne prend qu'un seul bit de chacune d'entre elle.
Par la suite, il sera possible de déclarer une variable comme de type
champ_de_bits de cette façon :
struct
champ_de_bits champ1;
Et, pour accéder à chaque bit, il faudra agir exactement de la même
façon que pour les structures normales : il conviendra d'utiliser ce type
syntaxe :
champ1.bit1 = 0; // pour fixer le
bit1 à 0.
if(champ1.bit3
== 1)
{
//
Instructions à effectuer si champ1.bit3 est armé...
}
Nous verrons dans la quatrième partie de ce chapitre un exemple plus complet
de manipulation de champ de bits...
III:\
Les unions :
Les unions permettent de grouper plusieurs variables qui
peuvent être assimilées à un même espace mémoire. Ainsi, vous pouvez
définir une union de la façon qui suit :
union short_ou_long
{
short i;
long l;
} un_nombre; //
Exemple tiré de la doc de TIGCC...
Ici, vous pourrez définir le nombre correspondant à un_nombre
soit par une variable de type short,
soit par une variable de type long.
Le compilateur fera en sorte que l'espace mémoire alloué dans le programme
pour cette union corresponde à l'élément le plus long dans l'union. (Ici, le long
qui fait 4 octets, au lieu du short,
qui n'en fait que 2).
Ensuite, pour utiliser cette union, il vous suffit de
savoir que cela fonctionne de la même façon que pour les structures. Parc
contre, vous ne pourrez pas affecter une valeur à un_nombre.i
et à un_nombre.l en même
temps, puisque ces deux données sont situées au même emplacement dans la
mémoire.
Pour résumer, une union vous permet de définir une donnée
de plusieurs façons différentes, façon que vous pourrez choisir selon les
circonstances.
Nous verrons dans la quatrième partie de ce chapitre un exemple plus complet
de manipulation d'union...
IV:\
Exemple d'utilisation de structures, d'unions et champs
de bits :
Nous allons ici partir d'une structure définie dans la
doc de TIGCC : il s'agit de celle qui défini les pointeurs de type SYM_ENTRY.
En effet, on m'a déjà posé beaucoup de questions à son sujet, et je suis
d'avis que c'est la plus complète qui puisse être prise comme exemple ici...
De plus, si vous avez étudié le Chapitre
X traitant des manipulations de la VAT, vous avez déjà utilisé cette
structure, même sans le savoir.
Voilà comment cette structure est définie dans la doc du
ficher <vat.h> :
typedef struct
{
char name[8];
unsigned short compat;
union
{
unsigned
short flags_n;
struct
{
unsigned
short busy : 1,
local : 1,
flag1_5 : 1,
flag1_4 : 1,
collapsed
: 1,
twin : 1,
archived : 1,
in_view : 1;
unsigned
short folder : 1,
overwritten : 1,
checked : 1,
hidden : 1,
locked
: 1,
statvar : 1,
graph_ref_1 : 1,
graph_ref_0 : 1;
} bits;
} flags;
unsigned short handle;
} SYM_ENTRY;
Comme nous pouvons ici le voir, les structures de type SYM_ENTRY
contiendront toutes :
- Une variable de type char
de 8 caractères, nommée name.
- ET une variable de type unsigned
short, nommée compat.
- ET Une union, nommée flags, qui permet d'utiliser :
- SOIT une variable de type unsigned
short, nommée flags_n.
- SOIT une structure, nommée bits, qui regroupe en fait
deux champs de bits.
- ET, enfin, une variable de type unsigned
short, nommée handle.
A partir de cette définition, on peut savoir comment accéder
aux différents composants qui constituent cette structure : (On supposera qu'on
a défini un pointeur de ce type en faisant SYM_ENTRY
*nom_pointeur; et que ce pointeur pointe vers une variable. Voir Chapitre
X sur les manipulations de la VAT pour plus d'informations).
Par exemple, pour tester la valeur du
bit nommé archived, on peut faire : if(nom_pointeur->flags.bits.archived==1)
{/*Instructions à exécuter*/}
Voilà, à présent, vous savez tout ce qui est nécessaire
pur manipuler des structures, et autres, bref pour grouper des données. Je vous
conseille de vous entraîner un peu à les utiliser, même si vous ne les emploierez
pas en permanence dans vos programmes... En effet, on ne penses pas souvent
à utiliser ce genre de données, mais, quand on y réfléchit bien, elles s'avèrent
être fort pratiques !
Retour au menu général
Chapitre
XXIII
|
|