Home   Archives    Hardware   Programmation   Challenges   Forum   Le Mag    Faq   La Communauté   L'Equipe
 
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

Les raccourcis
 

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


 


Copyright © Ti-Fr v2.0 1999-2002