English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Tutoriel de base C

Contrôle de flux C

Fonctions en C

Tableaux en C

Pointeurs en C

Chains de caractères en C

Structure de C

Fichier C

Autres C

Manuel de référence C

Structures (struct) en C

Dans ce tutoriel, vous apprendrez le type de structure en programmation C. Vous apprendrez à définir et utiliser les structures à l'aide d'exemples.

Dans la programmation C, il est parfois nécessaire de stocker plusieurs attributs d'entités. Une entité n'a pas besoin d'avoir toutes les informations d'un seul type. Elle peut avoir différents attributs de types de données différents.

Les tableaux C permettent de définir des variables qui peuvent stocker des éléments de données du même type.structureest un autre type de données utilisateur personnalisé disponible en C, qui permet de stocker différents éléments de données.

Les structures sont utilisées pour représenter un enregistrement, supposons que vous vouliez suivre les dynamiques des livres dans la bibliothèque, vous pourriez avoir besoin de suivre les propriétés suivantes de chaque livre :

  • Titre

  • Auteur

  • Sujet

  • Book ID

Définir la structure

Pour définir une structure, vous devez utiliser struct mot-clé. La directive struct définit un nouveau type de données contenant plusieurs membres, la syntaxe de la directive struct est la suivante :

struct tag { 
    membre-list
    membre-list 
    membre-list  
    ...
} variable-liste ;

tag est une étiquette de structure.

membre-list est une définition de variable standard, par exemple int i; ou float f, ou d'autres définitions de variables valides.

variable-list Les variables de structure, définies à la fin de la structure, avant le dernier point-virgule, vous pouvez spécifier une ou plusieurs variables de structure. Voici comment déclarer la structure Book :

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

En général,tag, membre-list, variable-list ce 3 au moins une partie doit apparaître 2 des. Voici un exemple :

//Cette déclaration déclare une structure qui possède3un membre de la structure, à savoir un entier a, un caractère b et un double c
//et déclare également la variable de structure s1
//Cette structure n'a pas de tag spécifié
struct 
{
    int a;
    char b;
    double c;
} s1;
 
//Cette déclaration déclare une structure qui possède3un membre de la structure, à savoir un entier a, un caractère b et un double c
//Le tag de la structure est nommé SIMPLE, sans déclarer de variable
struct SIMPLE
{
    int a;
    char b;
    double c;
};
//Déclarer une variable de structure avec le tag SIMPLE, et déclarer également la variable t1、t2、t3
struct SIMPLE t1, t2[20], *t3;
 
//On peut également créer de nouveaux types avec typedef
typedef struct
{
    int a;
    char b;
    double c; 
} Simple2;
//Maintenant on peut utiliser Simple2Déclarer de nouvelles variables de structure avec un type de déclaration
Simple2 u1, u2[20], *u3;

Dans la déclaration ci-dessus, la première et la deuxième déclarations sont traitées comme deux types complètement différents par le compilateur, même si leurs listes de membres sont identiques, si on fait en sorte que t3&s1est illégal.

Les membres des structures peuvent contenir d'autres structures, ou des pointeurs vers le type de la structure elle-même, et généralement cet usage des pointeurs est pour réaliser des structures de données plus avancées comme les listes et les arbres, etc.

//La déclaration de cette structure contient d'autres structures
struct COMPLEX
{
    char string[100];
    struct SIMPLE a;
};
 
//La déclaration de cette structure contient un pointeur vers le type de cette structure
struct NODE
{
    char string[100];
    struct NODE *next_node;
};

Si deux structures se contiennent mutuellement, il faut déclarer une des structures de manière incomplète, comme ci-dessous :

struct B;    //Déclaration incomplète de la structure B
 
//La structure A contient un pointeur vers la structure B
struct A
{
    struct B *partenaire;
    //membres autres;
};
 
//La structure B contient un pointeur vers la structure A, après la déclaration de A, B est également déclarée.
struct B
{
    struct A *partenaire;
    //membres autres;
};

Initialisation des variables de structure

Comme pour d'autres types de variables, on peut spécifier des valeurs initiales pour les variables de structure lors de leur définition.

#include <stdio.h>
 
struct Books
{
   char  title[50];
   char  author[50];
   char  subject[100];
   int   book_id;
} book = {"Langage C", "w3codebox", "Langage de programmation", 123456};
 
int main();
{
    printf("Titre du livre : %s\nAuteur : %s\nThème : %s\nBookID %d\n", book.title, book.author, book.subject, book.book_id);
}

Le résultat de l'exécution est :

Titre : C Language
Auteur : w3codebox
Sujet : Programming Language
BookID 123456

Accéder aux membres de la structure

Pour accéder aux membres de la structure, nous utilisonsL'opérateur d'accès aux membres (.).L'opérateur d'accès aux membres est un point qui se trouve entre le nom de la variable de structure et le membre de structure que nous voulons accéder. Vous pouvez utiliser struct Les mots-clés pour définir les variables de type structure. L'exemple suivant montre l'utilisation des structures :

#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;        /* Déclaration de Book1,de type Books */
   struct Books Book2;        /* Déclaration de Book2,de type Books */
 
   /* Book1 Détails */
   strcpy( Book1.title, "C Programming Language");
   strcpy( Book1.author, "Nuha Ali"); 
   strcpy( Book1.subject, "C Programming Language Tutorial");
   Book1.book_id = 6495407;
 
   /* Book2 Détails */
   strcpy( Book2.title, "JAVA Programming Language");
   strcpy( Book2.author, "Seagull Ali");
   strcpy( Book2.subject, "JAVA Programming Language Tutorial");
   Book2.book_id = 6495700;
 
   /* Sortie Book1 L'adresse de l'information */
   printf("Book 1 Titre : %s\n", Book1.title);
   printf("Book 1 Auteur : %s\n", Book1.author);
   printf("Book 1 Sujet : %s\n", Book1.subject);
   printf("Book 1 Numéro : %d\n", Book1.book_id);
 
   /* Sortie Book2 L'adresse de l'information */
   printf("Book 2 Titre : %s\n", Book2.title);
   printf("Book 2 Auteur : %s\n", Book2.author);
   printf("Book 2 Sujet : %s\n", Book2.subject);
   printf("Book 2 Numéro : %d\n", Book2.book_id);
 
   return 0;
}

Lorsque le code ci-dessus est compilé et exécuté, il génère les résultats suivants :

Book 1 Titre : C Programming Language
Book 1 Auteur : Nuha Ali
Book 1 Sujet : C Programming Language Tutorial
Book 1 Numéro : 6495407
Book 2 Titre : JAVA Programming Language
Book 2 Auteur : Seagull Ali
Book 2 Sujet : JAVA Programming Language Tutorial
Book 2 Numéro : 6495700

Structure en tant que paramètre de fonction

Vous pouvez passer une structure en tant que paramètre de fonction, de la même manière que vous le feriez pour un autre type de variable ou un pointeur. Vous pouvez accéder aux variables de structure de la même manière que dans l'exemple précédent :

#include <stdio.h>
#include <string.h>
 
struct Books
{
   char  title[50];
   char  author[50];
   char  subject[100];
   int   book_id;
};
 
/* Déclaration de la fonction */
void printBook(struct Books book);
int main( )
{
   struct Books Book1;        /* Déclaration de Book1,de type Books */
   struct Books Book2;        /* Déclaration de Book2,de type Books */
 
   /* Book1 Détails */
   strcpy( Book1.title, "C Programming Language");
   strcpy( Book1.author, "Nuha Ali"); 
   strcpy( Book1.subject, "C Programming Language Tutorial");
   Book1.book_id = 6495407;
 
   /* Book2 Détails */
   strcpy( Book2.title, "JAVA Programming Language");
   strcpy( Book2.author, "Seagull Ali");
   strcpy( Book2.subject, "JAVA Programming Language Tutorial");
   Book2.book_id = 6495700;
 
   /* Sortie Book1 L'adresse de l'information */
   printBook(Book1 );
 
   /* Sortie Book2 L'adresse de l'information */
   printBook(Book2 );
 
   return 0;
}
void printBook(struct Books book)
{
   printf("Book titre : %s\n", book.title);
   printf("Book auteur : %s\n", book.author);
   printf("Book sujet : %s\n", book.subject);
   printf("Book numéro : %d\n", book.book_id);
}

Lorsque le code ci-dessus est compilé et exécuté, il génère les résultats suivants :

Book Titre : C Programming Language
Book Auteur : Nuha Ali
Book Thème : C Programming Language Tutorial
Book Numéro : 6495407
Book Titre : JAVA Programming Language
Book Auteur : Seagull Ali
Book Thème : JAVA Programming Language Tutorial
Book Numéro : 6495700

Pointeur vers une structure

Vous pouvez définir un pointeur vers une structure de la même manière que vous définiriez un pointeur vers un autre type de variable, comme suit :

struct Books *struct_pointer;

Maintenant, vous pouvez stocker l'adresse de la variable de structure dans la variable de pointeur définie ci-dessus. Pour trouver l'adresse de la variable de structure, placez l'opérateur & devant le nom de la structure, comme suit :

struct_pointer = &Book1;

Pour accéder aux membres de la structure via un pointeur vers cette structure, vous devez utiliser -l'opérateur, comme suit :

struct_pointer-title;

Laissez-nous utiliser un pointeur de structure pour réécrire l'exemple précédent, ce qui vous aidera à comprendre le concept de pointeur de structure :

#include <stdio.h>
#include <string.h>
 
struct Books
{
   char  title[50];
   char  author[50];
   char  subject[100];
   int   book_id;
};
 
/* Déclaration de la fonction */
void printBook( struct Books *book );
int main( )
{
   struct Books Book1;        /* Déclaration de Book1,de type Books */
   struct Books Book2;        /* Déclaration de Book2,de type Books */
 
   /* Book1 Détails */
   strcpy( Book1.title, "C Programming Language");
   strcpy( Book1.author, "Nuha Ali"); 
   strcpy( Book1.subject, "C Programming Language Tutorial");
   Book1.book_id = 6495407;
 
   /* Book2 Détails */
   strcpy( Book2.title, "JAVA Programming Language");
   strcpy( Book2.author, "Seagull Ali");
   strcpy( Book2.subject, "JAVA Programming Language Tutorial");
   Book2.book_id = 6495700;
 
   /* En transmettant Book1 pour afficher Book1 L'adresse de l'information */
   printBook( &Book1 );
 
   /* En transmettant Book2 pour afficher Book2 L'adresse de l'information */
   printBook( &Book2 );
 
   return 0;
}
void printBook( struct Books *book )
{
   printf( "Book Titre : %s\n", book->title);
   printf( "Book Auteur : %s\n", book->author);
   printf( "Book Thème : %s\n", book->subject);
   printf( "Book Numéro : %d\n", book->book_id);
}

Lorsque le code ci-dessus est compilé et exécuté, il génère les résultats suivants :

Book Titre : C Programming Language
Book Auteur : Nuha Ali
Book Thème : C Programming Language Tutorial
Book Numéro : 6495407
Book Titre : JAVA Programming Language
Book Auteur : Seagull Ali
Book Thème : JAVA Programming Language Tutorial
Book Numéro : 6495700

Domaine de bits

Certaines informations n'ont pas besoin d'occuper un octet complet lors de leur stockage, mais ne nécessitent que quelques ou un bit binaire. Par exemple, lors de l'entreposage d'une variable de commutation, seules les valeurs 0 et 1 Deux états, utilisés 1 Le domaine binaire est suffisant. Pour économiser de l'espace de stockage et simplifier le traitement, le langage C propose également une structure de données appelée "domaine de bits" ou "segment de bits".

Le "domaine de bits" consiste à diviser les bits d'un octet en plusieurs zones différentes et à indiquer le nombre de bits de chaque zone. Chaque domaine a un nom de domaine, qui permet d'effectuer des opérations sur le nom de domaine dans le programme. De cette manière, plusieurs objets différents peuvent être représentés par un domaine de bits binaire d'un octet.

Exemple typique :

  • Avec 1 Lorsque un bit binaire stocke une quantité de bascule, il n'y a que 0 et 1 Deux états.

  • Lecture de format de fichier externe - peut lire des formats de fichiers non standard. Par exemple :9 Entier des bits.

La définition des champs bits et l'explication des variables de champ bits

La définition des champs bits est similaire à la définition des structures, et sa forme est :

struct Nom_de_la_structure_de_champs_bits 
{
 Liste des champs bits
};

La forme de la liste des champs bits est :

Symbologie de type - Nom du champ bits: Longueur du champ bits

Par exemple :

struct bs{
    int a:8;
    int b:2;
    int c:6;
} data;

Explication data est la variable bs, elle occupe deux octets. Parmi eux, le champ bits a occupe 8 Bits, le champ bits b occupe 2 Bits, le champ bits c occupe 6 Bits.

Laissons-nous voir un autre 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;

Dans ce cas, packed_struct contient 6 Un membre : quatre 1 Identificateur de bits f1..f4, un 4 Bits type et un 9 Bits my_int.

Il y a quelques points à noter sur la définition des champs bits :

  • Un champ bits est stocké dans le même octet, comme si l'espace restant dans un octet n'est pas suffisant pour stocker un autre champ bits, il sera stocké à partir de la prochaine unité. Il est également possible d'indiquer intentionnellement que certains champs bits commencent à la prochaine unité. Par exemple :

    struct bs{
        unsigned a:4;
        unsigned :4;    /* Domaine vide */
        unsigned b:4;    /* Commence à stocker à partir de la prochaine unité */
        unsigned c:4
    }

    Dans cette définition de champ bits, a occupe le premier octet de 4 Bits, après 4 Bits remplis de 0 indiquent qu'ils ne sont pas utilisés, b commence au deuxième octet, occupe 4 Bits, c occupe 4 Bits.

  • Comme les champs bits ne peuvent pas dépasser deux octets, la longueur des champs bits ne peut pas dépasser la longueur d'un octet, c'est-à-dire ne pas dépasser8Bits binaires. Si la longueur maximale est supérieure à la longueur du nombre entier de l'ordinateur, certains compilateurs peuvent permettre la chevauchement de la mémoire des champs, d'autres compilateurs peuvent stocker une partie supérieure à un champ dans le prochain mot.

  • Les champs bits peuvent être des champs bits anonymes, dans ce cas, ils ne servent qu'à combler des espaces ou à ajuster la position. Les champs bits anonymes ne peuvent pas être utilisés. Par exemple :

    struct k{
        int a:1;
        int :2;    /* Ce 2 Les bits ne peuvent pas être utilisés */
        int b:3;
        int c:2;
    };

D'après l'analyse ci-dessus, on peut voir que les champs bits sont essentiellement un type de structure, mais leurs membres sont répartis en positions binaires.

L'utilisation des champs bits

L'utilisation des champs bits et des membres des structures est la même, et sa forme générale est :

Nom de la variable de champ bits.Nom du champ bits
Nom de la variable de champ bits->Nom du champ bits

Les champs bits permettent de sortir en divers formats.

Voyons un exemple ci-dessous :

main(){
    struct bs{
        unsigned a:1;
        unsigned b:3;
        unsigned c:4;
    } bit,*pbit;
    bit.a=1;    /* Affecter une valeur au domaine de bits (il faut noter que l'affectation ne peut pas dépasser la plage autorisée du domaine de bits) */
    bit.b=7;    /* Affecter une valeur au domaine de bits (il faut noter que l'affectation ne peut pas dépasser la plage autorisée du domaine de bits) */
    bit.c=15;    /* Affecter une valeur au domaine de bits (il faut noter que l'affectation ne peut pas dépasser la plage autorisée du domaine de bits) */
    printf("%d,%d,%d\n",bit.a,bit.b,bit.c);    /* Afficher le contenu des trois domaines au format de nombre entier */
    pbit=&bit;    /* Envoyer l'adresse de la variable de domaine de bits bit à la variable de pointeur pbit */
    pbit->a=0;    /* Redéfinir à nouveau la valeur du domaine de bits a en 0 */
    pbit->b&=3;    /* Il a utilisé l'opérateur de calcul de bits composé "&=", ce qui équivaut à : pbit->b=pbit->b&3,la valeur originale du domaine de bits b 7,et 3 Le résultat de l'opération de conjonction bit à bit est 3(111&011=011,valeur décimale 3) */
    pbit->c|=1;    /* Il a utilisé l'opérateur de calcul de bits composé "|=", ce qui équivaut à : pbit->c=pbit->c|1,其结果为 15 */
    printf("%d,%d,%d\n",pbit->a,pbit->b,pbit->c);    /* Les valeurs de ces trois domaines ont été affichées de manière pointée */
}

Dans l'exemple de programme suivant, la structure de domaine de bits bs est définie, avec trois domaines de bits a, b, c. Cela montre que les domaines de bits peuvent également être utilisés avec des pointeurs.

Mot-clé typedef

Nous utilisons le mot-clé typedef pour créer des alias pour les types de données. Il est généralement utilisé avec les structures pour simplifier la syntaxe de déclaration des variables.

Ce code

struct Distance{
    int feet;
    float inch;
};
int main() {
    struct Distance d1, d2;
}

est équivalent à

typedef struct Distance{
    int feet;
    float inch;
} distances;
int main() {
    distances d1, d2;
}

structure imbriquée

Vous pouvez créer des structures à l'intérieur des structures en programmation C. Par exemple,

struct complex
{
 int imag;
 float real;
};
struct number
{
   struct complex comp;
   int integers;
} num1, num2;

Supposons, vous devez configurer num2La valeur de la variable imag est11,怎么做呢?看下面示例:

num;2.comp.imag =; 11;

    Pourquoi utiliser des structures en C ?

    Supposons que vous vouliez stocker des informations sur une personne : il/Son nom, numéro d'identité et salaire. Vous pouvez créer des variables différentes comme name, citNo et salary pour stocker cette information.

    Que faire si vous devez stocker les informations de plusieurs personnes ? Maintenant, vous devez créer des variables différentes pour chaque information de chaque personne : name1,citNo1,salary1,name2,citNo2,salary2et al.

    Il est préférable de regrouper toutes les informations pertinentes sous une seule structure nommée Person et de les utiliser pour chaque personne.

    Plus sur les structures