Structures de données : Tableaux unidimensionnels et bidimensionnels en C

Cet article explore les concepts fondamentaux des tableaux, en commençant par les tableaux unidimensionnels, leur déclaration, initialisation et manipulation. Il aborde ensuite les tableaux bidimensionnels, couvrant des sujets similaires. Des exemples de code et des explications sur leur stockage en mémoire sont fournis pour une meilleure compréhension. Enfin, il présente le concept des tableaux de longueur variable introduits en C99 et des exercices pratiques illustrant l'application des tableaux.

Tableaux unidimensionnels

Concept

Un tableau est une collection de données du même type. Il peut contenir un ou plusieurs éléments, mais jamais zéro. Les tableaux peuvent être unidimensionnels ou multidimensionnels, les tbaleaux bidimensionnels étant les plus courants.

Déclaration et Initialisation

La syntaxe générale pour déclarer un tableau unidimensionnel est :

type nom_tableau[taille_constante];
  • type : Spécifie le type des éléments stockés dans le tableau.
  • nom_tableau : Le nom donné au tableau.
  • taille_constante : Un entier constant définissant le nombre d'éléments dans le tableau.

L'initialisation d'un tableau peut être effectuée de plusieurs manières :

  • Initialisation complète : Tous les éléments sont explicitement assignés. ``` int nombres[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
  • Initialisation partielle : Seuls certains éléments sont initialisés ; les éléments restants sont mis à zéro. ``` int nombres[10] = { 1, 2, 3 };
  • Erreur d'initialisation : Tenter d'initialiser avec plus d'éléments que la taille déclarée est une erreur. ``` // int erreurs[3] = { 1, 2, 3, 4, 5 }; // Ceci est une erreur
    
    

Type des Tableaux

Chaque tableau possède un type spécifique. Le type d'un tableau arr déclaré comme type arr\[taille\] est type \[taille\].

int tableau_entiers[10]; // Le type est int[10]
   char tableau_caracteres[5]; // Le type est char[5]
   

Utilisation des Tableaux Unidimensionnels

L'accès aux éléments d'un tableau se fait via leur indice, qui commence à 0. Pour un tableau de taille n, les indices vont de 0 à n-1.

L'opérateur d'accès aux éléments est \[\].

int mon_tableau[6] = { 1, 2, 3, 4, 5, 6 };
   printf("%d\n", mon_tableau[0]); // Affiche le premier élément (1)
   

Affichage des éléments :

Une boucle est couramment utilisée pour parcourir et afficher tous les éléments.

int mon_tableau[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
   for (int i = 0; i < 10; i++) {
       printf("%d ", mon_tableau[i]);
   }
   printf("\n");
   

Saisie des éléments :

De même, une boucle peut être utilisée pour lire des valeurs saisies par l'utilisateur et les stocker dans le tableau.

int mon_tableau[10] = { 0 };
   printf("Entrez 10 nombres :\n");
   for (int i = 0; i < 10; i++) {
       scanf("%d", &mon_tableau[i]);
   }
   printf("Vous avez entré :\n");
   for (int i = 0; i < 10; i++) {
       printf("%d ", mon_tableau[i]);
   }
   printf("\n");
   

Stockage en Mémoire

Les tableaux sont stockés de manière contiguë en mémoire. L'adresse de chaque élément successif augmente par la taille d'un élément. L'opérateur %p peut être utilisé pour afficher les adresses mémoire.

int mon_tableau[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
   for (int i = 0; i < 10; i++) {
       printf("Adresse de arr[%d] : %p\n", i, (void*)&mon_tableau[i]);
   }
   

La différence d'adresse entre deux éléments consécutifs est égale à la taille en octets du type d'élément (par exemple, 4 octets pour un int).

Calcul du Nombre d'Éléments

Le nombre total d'éléments d'un tableau peut être calculé en divisant la taille totale du tableau par la taille d'un seul élément.

int mon_tableau[10] = { 0 };
   size_t taille_element = sizeof(mon_tableau[0]);
   size_t taille_tableau = sizeof(mon_tableau);
   int nombre_elements = taille_tableau / taille_element;
   printf("Le tableau contient %d éléments.\n", nombre_elements);
   

Tableaux bidimensionnels

Concept

Un tableau bidimnesionnel peut être vu comme un tableau dont les éléments sont eux-mêmes des tableaux unidimensionnels. Il représente une structure de type grille ou matrice.

Déclaration

La syntaxe pour déclarer un tableau bidimensionnel est :

type nom_tableau[constante_lignes][constante_colonnes];
  • constante_lignes : Le nombre de lignes.
  • constante_colonnes : Le nombre de colonnes.
int matrice[3][5]; // Une matrice de 3 lignes et 5 colonnes d'entiers.

Initialisation

L'initialisation peut se faire de manière similaire aux tableaux unidimensionnels, en utilisant des accolades imbriquées pour représenter les lignes.

  • Initialisation complète par ligne : ``` int matrice[2][3] = { { 1, 2, 3 }, { 4, 5, 6 } };
  • Initialisation complète sans accolades internes : Les éléments sont listés séquentiellement, et les compilateurs remplissent ligne par ligne. ``` int matrice[2][3] = { 1, 2, 3, 4, 5, 6 };
  • Omission de la première dimension : Lors de l'initialisation, le nombre de lignes peut être omis, mais pas le nombre de colonnes. ``` int matrice[][3] = { 1, 2, 3, 4, 5, 6 }; // 2 lignes, 3 colonnes sont déduites
    
    

Utilisation

L'accès à un élément spécifique d'un tableau bidimensionnel se fait en spécifiant l'indice de la ligne et celui de la colonne.

int matrice[3][5] = { { 1, 2, 3, 4, 5 },
                      { 6, 7, 8, 9, 10 },
                      { 11, 12, 13, 14, 15 } };
   printf("%d\n", matrice[1][2]); // Affiche l'élément à la ligne 1, colonne 2 (valeur 8)
   

Saisie et Affichage :

Des boucles imbriquées sont utilisées pour parcourir les lignes et les colonnes.

int matrice[3][5] = { { 0 } };
   printf("Entrez les éléments de la matrice (3x5) :\n");
   for (int i = 0; i < 3; i++) {
       for (int j = 0; j < 5; j++) {
           scanf("%d", &matrice[i][j]);
       }
   }

   printf("La matrice entrée est :\n");
   for (int i = 0; i < 3; i++) {
       for (int j = 0; j < 5; j++) {
           printf("%d ", matrice[i][j]);
       }
       printf("\n");
   }
   

Stockage en Mémoire

Les éléments d'un tableau bidimensionnel sont également stockés de manière contiguë en mémoire, ligne par ligne. La différence d'adresse entre deux éléments consécutifs est toujours égale à la taille d'un élément.

int matrice[3][5];
   for (int i = 0; i < 3; i++) {
       for (int j = 0; j < 5; j++) {
           printf("Adresse de matrice[%d][%d] : %p\n", i, j, (void*)&matrice[i][j]);
       }
   }
   

Tableaux de Longueur Variable (C99)

La norme C99 a introduit la possibilité de déclarer des tableaux dont la taille est déterminée à l'exécution, à l'aide de variables. Ces tableaux sont appelés tableaux de longueur variable (VLA - Variable Length Array). Il est important de noter que la taille d'un VLA, une fois définie, ne peut plus être modifiée.

Note : Certains compilateurs, comme les versions récentes de Visual Studio, n'implémentent pas entièrement la fonctionnalité VLA.

#include <stdio.h>

   int main() {
       int taille;
       printf("Entrez la taille du tableau : ");
       scanf("%d", &taille);

       int tableau_variable[taille]; // Déclaration d'un VLA

       printf("Entrez %d éléments :\n", taille);
       for (int i = 0; i < taille; i++) {
           scanf("%d", &tableau_variable[i]);
       }

       printf("Les éléments entrés sont :\n");
       for (int i = 0; i < taille; i++) {
           printf("%d ", tableau_variable[i]);
       }
       printf("\n");

       return 0;
   }
   

Exercices Pratiques

1. Effet de Vague sur une Chaîne de Caractères

Cet exercice simule un effet visuel où des caractères d'une chaîne source apparaissent progressivement des extrémités vers le centre sur une chaîne de destination.

#include <stdio.h>
   #include <string.h>
   #include <windows.h> // Nécessaire pour Sleep et system("cls")
   #include <stdlib.h>  // Nécessaire pour system("cls")

   int main() {
       char source[] = "Je vous aime, France !";
       char destination[sizeof(source)]; // Assurez-vous que la taille est suffisante
       strcpy(destination, source); // Initialisation pour pouvoir effacer

       int debut = 0;
       int fin = strlen(source) - 1;

       // Initialiser la chaîne de destination avec des '*' pour l'effet visuel
       for(int i = 0; i < strlen(source); ++i) {
           destination[i] = '*';
       }
       destination[strlen(source)] = '\0'; // Terminer la chaîne

       while (debut <= fin) {
           destination[debut] = source[debut];
           destination[fin] = source[fin];

           system("cls"); // Efface l'écran
           printf("%s\n", destination);

           Sleep(150); // Pause de 150 ms

           debut++;
           fin--;
       }
       printf("%s\n", destination); // Affichage final
       return 0;
   }
   

2. Recherche Binaire (Binary Search)

La recherche binaire est un algorithme efficace pour trouver un élément dans un tableau trié. Elle divise l'espace de recherche par deux à chaque étape.

#include <stdio.h>

   int main() {
       int tableau_trie[] = { 2, 5, 8, 12, 16, 23, 38, 56, 72, 91 };
       int taille = sizeof(tableau_trie) / sizeof(tableau_trie[0]);
       int cle;
       int gauche = 0;
       int droite = taille - 1;
       int trouve = 0; // Indicateur si l'élément est trouvé

       printf("Entrez la valeur à rechercher : ");
       scanf("%d", &cle);

       while (gauche <= droite) {
           // Calculer le milieu de manière sécurisée pour éviter le dépassement
           int milieu = gauche + (droite - gauche) / 2;

           if (cle == tableau_trie[milieu]) {
               trouve = 1;
               printf("L'élément %d a été trouvé à l'indice %d.\n", cle, milieu);
               break;
           } else if (cle < tableau_trie[milieu]) {
               // L'élément cherché est dans la moitié gauche
               droite = milieu - 1;
           } else {
               // L'élément cherché est dans la moitié droite
               gauche = milieu + 1;
           }
       }

       if (!trouve) {
           printf("L'élément %d n'a pas été trouvé dans le tableau.\n", cle);
       }

       return 0;
   }
   

La recherche binaire est particulièrement avantageuse pour de très grands ensembles de données par rapport à une recherche linéaire simple.

Étiquettes: C tableaux structures de données algorithmes recherche binaire

Publié le 14 juillet à 22h21