C - Structures

Les tableaux permettent de définir le type de variables pouvant contenir plusieurs éléments de données du même type. De mêmestructure est un autre type de données défini par l'utilisateur disponible en C qui permet de combiner des éléments de données de différents types.

Les structures sont utilisées pour représenter un enregistrement. Supposons que vous souhaitiez garder une trace de vos livres dans une bibliothèque. Vous souhaiterez peut-être suivre les attributs suivants pour chaque livre -

  • Title
  • Author
  • Subject
  • ID du livre

Définition d'une structure

Pour définir une structure, vous devez utiliser le structdéclaration. L'instruction struct définit un nouveau type de données, avec plus d'un membre. Le format de l'instruction struct est le suivant -

struct [structure tag] {

   member definition;
   member definition;
   ...
   member definition;
} [one or more structure variables];

le structure tagest facultative et chaque définition de membre est une définition de variable normale, telle que int i; ou float f; ou toute autre définition de variable valide. À la fin de la définition de la structure, avant le point-virgule final, vous pouvez spécifier une ou plusieurs variables de structure mais c'est facultatif. Voici la façon dont vous déclareriez la structure Book -

struct Books {
   char  title[50];
   char  author[50];
   char  subject[100];
   int   book_id;
} book;

Accès aux membres de la structure

Pour accéder à n'importe quel membre d'une structure, nous utilisons le member access operator (.). L'opérateur d'accès au membre est codé comme un point entre le nom de la variable de structure et le membre de la structure auquel nous souhaitons accéder. Vous utiliseriez le mot-cléstructpour définir des variables de type structure. L'exemple suivant montre comment utiliser une structure dans un programme -

#include <stdio.h>
#include <string.h>
 
struct Books {
   char  title[50];
   char  author[50];
   char  subject[100];
   int   book_id;
};
 
int main( ) {

   struct Books Book1;        /* Declare Book1 of type Book */
   struct Books Book2;        /* Declare Book2 of type Book */
 
   /* book 1 specification */
   strcpy( Book1.title, "C Programming");
   strcpy( Book1.author, "Nuha Ali"); 
   strcpy( Book1.subject, "C Programming Tutorial");
   Book1.book_id = 6495407;

   /* book 2 specification */
   strcpy( Book2.title, "Telecom Billing");
   strcpy( Book2.author, "Zara Ali");
   strcpy( Book2.subject, "Telecom Billing Tutorial");
   Book2.book_id = 6495700;
 
   /* print Book1 info */
   printf( "Book 1 title : %s\n", Book1.title);
   printf( "Book 1 author : %s\n", Book1.author);
   printf( "Book 1 subject : %s\n", Book1.subject);
   printf( "Book 1 book_id : %d\n", Book1.book_id);

   /* print Book2 info */
   printf( "Book 2 title : %s\n", Book2.title);
   printf( "Book 2 author : %s\n", Book2.author);
   printf( "Book 2 subject : %s\n", Book2.subject);
   printf( "Book 2 book_id : %d\n", Book2.book_id);

   return 0;
}

Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -

Book 1 title : C Programming
Book 1 author : Nuha Ali
Book 1 subject : C Programming Tutorial
Book 1 book_id : 6495407
Book 2 title : Telecom Billing
Book 2 author : Zara Ali
Book 2 subject : Telecom Billing Tutorial
Book 2 book_id : 6495700

Structures comme arguments de fonction

Vous pouvez transmettre une structure en tant qu'argument de fonction de la même manière que vous transmettez toute autre variable ou pointeur.

#include <stdio.h>
#include <string.h>
 
struct Books {
   char  title[50];
   char  author[50];
   char  subject[100];
   int   book_id;
};

/* function declaration */
void printBook( struct Books book );

int main( ) {

   struct Books Book1;        /* Declare Book1 of type Book */
   struct Books Book2;        /* Declare Book2 of type Book */
 
   /* book 1 specification */
   strcpy( Book1.title, "C Programming");
   strcpy( Book1.author, "Nuha Ali"); 
   strcpy( Book1.subject, "C Programming Tutorial");
   Book1.book_id = 6495407;

   /* book 2 specification */
   strcpy( Book2.title, "Telecom Billing");
   strcpy( Book2.author, "Zara Ali");
   strcpy( Book2.subject, "Telecom Billing Tutorial");
   Book2.book_id = 6495700;
 
   /* print Book1 info */
   printBook( Book1 );

   /* Print Book2 info */
   printBook( Book2 );

   return 0;
}

void printBook( struct Books book ) {

   printf( "Book title : %s\n", book.title);
   printf( "Book author : %s\n", book.author);
   printf( "Book subject : %s\n", book.subject);
   printf( "Book book_id : %d\n", book.book_id);
}

Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -

Book title : C Programming
Book author : Nuha Ali
Book subject : C Programming Tutorial
Book book_id : 6495407
Book title : Telecom Billing
Book author : Zara Ali
Book subject : Telecom Billing Tutorial
Book book_id : 6495700

Pointeurs vers des structures

Vous pouvez définir des pointeurs vers des structures de la même manière que vous définissez un pointeur vers toute autre variable -

struct Books *struct_pointer;

Vous pouvez maintenant stocker l'adresse d'une variable de structure dans la variable de pointeur définie ci-dessus. Pour trouver l'adresse d'une variable de structure, placez le signe '&'; opérateur avant le nom de la structure comme suit -

struct_pointer = &Book1;

Pour accéder aux membres d'une structure à l'aide d'un pointeur vers cette structure, vous devez utiliser l'opérateur → comme suit -

struct_pointer->title;

Réécrivons l'exemple ci-dessus en utilisant un pointeur de structure.

#include <stdio.h>
#include <string.h>
 
struct Books {
   char  title[50];
   char  author[50];
   char  subject[100];
   int   book_id;
};

/* function declaration */
void printBook( struct Books *book );
int main( ) {

   struct Books Book1;        /* Declare Book1 of type Book */
   struct Books Book2;        /* Declare Book2 of type Book */
 
   /* book 1 specification */
   strcpy( Book1.title, "C Programming");
   strcpy( Book1.author, "Nuha Ali"); 
   strcpy( Book1.subject, "C Programming Tutorial");
   Book1.book_id = 6495407;

   /* book 2 specification */
   strcpy( Book2.title, "Telecom Billing");
   strcpy( Book2.author, "Zara Ali");
   strcpy( Book2.subject, "Telecom Billing Tutorial");
   Book2.book_id = 6495700;
 
   /* print Book1 info by passing address of Book1 */
   printBook( &Book1 );

   /* print Book2 info by passing address of Book2 */
   printBook( &Book2 );

   return 0;
}

void printBook( struct Books *book ) {

   printf( "Book title : %s\n", book->title);
   printf( "Book author : %s\n", book->author);
   printf( "Book subject : %s\n", book->subject);
   printf( "Book book_id : %d\n", book->book_id);
}

Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -

Book title : C Programming
Book author : Nuha Ali
Book subject : C Programming Tutorial
Book book_id : 6495407
Book title : Telecom Billing
Book author : Zara Ali
Book subject : Telecom Billing Tutorial
Book book_id : 6495700

Champs de bits

Les champs de bits permettent le conditionnement des données dans une structure. Ceci est particulièrement utile lorsque la mémoire ou le stockage de données est limité. Des exemples typiques incluent -

  • Emballage de plusieurs objets dans un mot machine. par exemple, les drapeaux 1 bit peuvent être compactés.

  • Lecture de formats de fichiers externes - des formats de fichiers non standard peuvent être lus, par exemple des entiers de 9 bits.

C nous permet de faire cela dans une définition de structure en mettant: longueur en bits après la variable. Par exemple -

struct packed_struct {
   unsigned int f1:1;
   unsigned int f2:1;
   unsigned int f3:1;
   unsigned int f4:1;
   unsigned int type:4;
   unsigned int my_int:9;
} pack;

Ici, le package_struct contient 6 membres: Quatre indicateurs 1 bit f1..f3, un type 4 bits et un my_int 9 bits.

C emballe automatiquement les champs de bits ci-dessus de manière aussi compacte que possible, à condition que la longueur maximale du champ soit inférieure ou égale à la longueur de mot entier de l'ordinateur. Si ce n'est pas le cas, certains compilateurs peuvent autoriser le chevauchement de mémoire pour les champs tandis que d'autres stockent le champ suivant dans le mot suivant.