Langage C/C++

Guide : Les Tableaux en C – Cas Particuliers

Les tableaux en langage C sont une structure de données fondamentale qui permet de gérer efficacement des collections d’éléments du même type. Ce guide aborde les cas particuliers et nuances dans la manipulation des tableaux.


1. Déclaration de tableaux avec tailles dynamiques

En C, la taille d’un tableau est généralement définie lors de sa déclaration. Cependant, une taille dynamique peut être spécifiée avec des pointeurs ou en utilisant une allocation dynamique.

Exemple :

#include <stdio.h>
#include <stdlib.h>

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

    int *tableau = (int *)malloc(n * sizeof(int));
    if (tableau == NULL) {
        printf("Allocation mémoire échouée.\n");
        return 1;
    }

    for (int i = 0; i < n; i++) {
        tableau[i] = i * i;
    }

    for (int i = 0; i < n; i++) {
        printf("tableau[%d] = %d\n", i, tableau[i]);
    }

    free(tableau);
    return 0;
}

2. Tableaux multidimensionnels

Les tableaux à plusieurs dimensions sont utiles pour les matrices ou les grilles.

Exemple d’un tableau 2D :

#include <stdio.h>

int main() {
    int tableau[3][4] = {
        {1, 2, 3, 4},
        {5, 6, 7, 8},
        {9, 10, 11, 12}
    };

    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 4; j++) {
            printf("tableau[%d][%d] = %d\n", i, j, tableau[i][j]);
        }
    }

    return 0;
}

3. Pointeurs et tableaux

Un tableau peut être manipulé via des pointeurs. Les noms de tableaux sont en réalité des pointeurs vers le premier élément.

Exemple avec pointeurs :

#include <stdio.h>

int main() {
    int tableau[5] = {10, 20, 30, 40, 50};
    int *ptr = tableau;

    for (int i = 0; i < 5; i++) {
        printf("Valeur à ptr[%d] = %d\n", i, *(ptr + i));
    }

    return 0;
}

4. Tableaux et fonctions

Les tableaux peuvent être passés en argument à une fonction. Cependant, seule l’adresse du premier élément est transmise, ce qui nécessite d’envoyer également la taille si besoin.

Exemple :

#include <stdio.h>

void afficherTableau(int tableau[], int taille) {
    for (int i = 0; i < taille; i++) {
        printf("tableau[%d] = %d\n", i, tableau[i]);
    }
}

int main() {
    int tableau[5] = {1, 2, 3, 4, 5};
    afficherTableau(tableau, 5);
    return 0;
}

5. Initialisation partielle

Un tableau peut être partiellement initialisé. Les valeurs non initialisées sont définies à 0 pour les tableaux statiques.

Exemple :

#include <stdio.h>

int main() {
    int tableau[10] = {1, 2, 3};
    for (int i = 0; i < 10; i++) {
        printf("tableau[%d] = %d\n", i, tableau[i]);
    }

    return 0;
}

6. Tableaux constants

Les tableaux déclarés avec const ne peuvent pas être modifiés après leur initialisation.

Exemple :

#include <stdio.h>

int main() {
    const int tableau[3] = {1, 2, 3};

    // tableau[0] = 10; // Erreur : modification d’un tableau constant.

    for (int i = 0; i < 3; i++) {
        printf("tableau[%d] = %d\n", i, tableau[i]);
    }

    return 0;
}

7. Tableaux de chaînes

Un tableau de chaînes est un tableau de pointeurs vers des chaînes de caractères.

Exemple :

#include <stdio.h>

int main() {
    const char *tableau[] = {"Bonjour", "le", "monde"};
    int taille = sizeof(tableau) / sizeof(tableau[0]);

    for (int i = 0; i < taille; i++) {
        printf("%s ", tableau[i]);
    }

    return 0;
}

8. Tableaux et mémoire partagée

Attention : la mémoire des tableaux déclarés dans une fonction est locale. Si vous devez conserver cette mémoire après la fin de la fonction, utilisez l’allocation dynamique.

Exemple incorrect :

int *creerTableau() {
    int tableau[5] = {1, 2, 3, 4, 5};
    return tableau; // Erreur : tableau local détruit après le retour.
}

Solution correcte :

#include <stdlib.h>

int *creerTableau() {
    int *tableau = (int *)malloc(5 * sizeof(int));
    for (int i = 0; i < 5; i++) {
        tableau[i] = i + 1;
    }
    return tableau;
}

Les tableaux en C offrent une flexibilité remarquable mais nécessitent une gestion attentive de la mémoire et des indices. Ce guide couvre des cas pratiques et avancés pour tirer pleinement parti des tableaux dans vos programmes.

En C, la fonction malloc (memory allocation) permet de créer des tableaux dynamiques, dont la taille peut être spécifiée à l’exécution. Contrairement aux tableaux statiques, leur taille n’est pas fixe et peut être ajustée en fonction des besoins de l’utilisateur ou du programme.


1. Utilisation de malloc pour créer des tableaux dynamiques

Étapes :

  1. Déclarez un pointeur du type des éléments du tableau.
  2. Utilisez malloc pour allouer un bloc de mémoire suffisant pour contenir les éléments du tableau.
  3. Vérifiez que l’allocation a réussi (le retour de malloc n’est pas NULL).
  4. Utilisez le tableau normalement avec l’opérateur d’indirection ([]).
  5. Libérez la mémoire allouée avec free lorsque le tableau n’est plus nécessaire.

Exemple : Tableau 1D (1 dimension)

#include <stdio.h>
#include <stdlib.h>

int main() {
    int n;

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

    // Allocation dynamique d'un tableau d'entiers
    int *tableau = (int *)malloc(n * sizeof(int));
    if (tableau == NULL) {
        printf("Échec de l'allocation mémoire.\n");
        return 1; // Quitte le programme en cas d'erreur
    }

    // Initialisation des éléments
    for (int i = 0; i < n; i++) {
        tableau[i] = i + 1;
    }

    // Affichage des éléments
    printf("Éléments du tableau : ");
    for (int i = 0; i < n; i++) {
        printf("%d ", tableau[i]);
    }
    printf("\n");

    // Libération de la mémoire
    free(tableau);

    return 0;
}

2. Utilisation de malloc pour des tableaux multidimensionnels

Exemple : Tableau 2D (2 dimensions)

Il existe deux approches courantes pour gérer des tableaux 2D dynamiques avec malloc.


Approche 1 : Allocation en une seule dimension

Les éléments sont alloués dans une seule grande zone mémoire, et l’accès aux éléments est géré manuellement.

#include <stdio.h>
#include <stdlib.h>

int main() {
    int lignes, colonnes;

    printf("Entrez le nombre de lignes et de colonnes : ");
    scanf("%d %d", &lignes, &colonnes);

    // Allocation d'un tableau 2D (linéarisé)
    int *tableau = (int *)malloc(lignes * colonnes * sizeof(int));
    if (tableau == NULL) {
        printf("Échec de l'allocation mémoire.\n");
        return 1;
    }

    // Initialisation et affichage
    for (int i = 0; i < lignes; i++) {
        for (int j = 0; j < colonnes; j++) {
            tableau[i * colonnes + j] = i + j; // Accès avec une formule
            printf("%d ", tableau[i * colonnes + j]);
        }
        printf("\n");
    }

    // Libération de la mémoire
    free(tableau);

    return 0;
}

Approche 2 : Allocation ligne par ligne

Chaque ligne est allouée séparément, ce qui donne une meilleure flexibilité mais requiert une gestion supplémentaire.

#include <stdio.h>
#include <stdlib.h>

int main() {
    int lignes, colonnes;

    printf("Entrez le nombre de lignes et de colonnes : ");
    scanf("%d %d", &lignes, &colonnes);

    // Allocation d'un tableau de pointeurs
    int **tableau = (int **)malloc(lignes * sizeof(int *));
    if (tableau == NULL) {
        printf("Échec de l'allocation mémoire.\n");
        return 1;
    }

    // Allocation pour chaque ligne
    for (int i = 0; i < lignes; i++) {
        tableau[i] = (int *)malloc(colonnes * sizeof(int));
        if (tableau[i] == NULL) {
            printf("Échec de l'allocation mémoire pour la ligne %d.\n", i);
            return 1;
        }
    }

    // Initialisation et affichage
    for (int i = 0; i < lignes; i++) {
        for (int j = 0; j < colonnes; j++) {
            tableau[i][j] = i * j; // Accès direct
            printf("%d ", tableau[i][j]);
        }
        printf("\n");
    }

    // Libération de la mémoire
    for (int i = 0; i < lignes; i++) {
        free(tableau[i]); // Libère chaque ligne
    }
    free(tableau); // Libère le tableau de pointeurs

    return 0;
}

3. Cas particulier : Redimensionner un tableau avec realloc

Si vous avez besoin d’agrandir ou de réduire la taille d’un tableau alloué dynamiquement, utilisez realloc.

Exemple :

#include <stdio.h>
#include <stdlib.h>

int main() {
    int n;

    printf("Entrez la taille initiale du tableau : ");
    scanf("%d", &n);

    int *tableau = (int *)malloc(n * sizeof(int));
    if (tableau == NULL) {
        printf("Échec de l'allocation mémoire.\n");
        return 1;
    }

    // Initialisation
    for (int i = 0; i < n; i++) {
        tableau[i] = i + 1;
    }

    // Augmenter la taille du tableau
    printf("Entrez la nouvelle taille du tableau : ");
    int nouveau_n;
    scanf("%d", &nouveau_n);

    tableau = (int *)realloc(tableau, nouveau_n * sizeof(int));
    if (tableau == NULL) {
        printf("Échec de l'allocation mémoire.\n");
        return 1;
    }

    // Initialisation des nouveaux éléments
    for (int i = n; i < nouveau_n; i++) {
        tableau[i] = i + 1;
    }

    // Affichage
    printf("Éléments du tableau redimensionné : ");
    for (int i = 0; i < nouveau_n; i++) {
        printf("%d ", tableau[i]);
    }
    printf("\n");

    // Libération
    free(tableau);

    return 0;
}

4. Bonnes pratiques avec malloc

  • Toujours vérifier que malloc a réussi (le pointeur n’est pas NULL).
  • Libérer la mémoire avec free dès qu’elle n’est plus nécessaire pour éviter les fuites de mémoire.
  • En cas d’échec de l’allocation avec malloc, assurez-vous que le programme gère proprement l’erreur (par exemple, en affichant un message ou en sortant du programme).

Avec ces notions, vous pouvez utiliser malloc efficacement pour gérer des tableaux dynamiques en C !

Autres articles

Guide : Implémenter get_iemedans des fichiers avec...
La fonction get_iemepermet de récupérer le i-ème élément d'un fichier...
Read more
Guide : Implémenter un Fichier en Tableau...
Les fichiers en tableaux circulaires (ou files d'attente circulaires )...
Read more
Guide : Fichiers en Tableaux Circulaires en...
Les tableaux circulaires (ou buffers circulaires) sont des structures de...
Read more
AZ

Recent Posts

Exercices Corrigés sur les Écarts Budgétaires

Exercice 1 : Calcul des Écarts sur Volume et Prix Contexte :Une entreprise a prévu…

52 minutes ago

Exemples de QCM sur le Contrôle Budgétaire (Contrôle de Gestion)

1. Généralités sur le Contrôle Budgétaire Question 1 : Quel est l’objectif principal du contrôle…

1 heure ago

Exemples de QCM Contrôle de Gestion et Pilotage de la Performance

Voici un QCM Contrôle de Gestion - Pilotage de la Performance bien conçu sur le…

2 heures ago

Modèle de Fiche d’Action Vierge dans Excel

Une fiche d’action est un outil essentiel pour planifier, suivre et gérer les tâches dans…

2 heures ago

Modèle de Fiche de Parrainage dans Word

La fiche de parrainage est bien plus qu’un simple document administratif. Elle constitue un outil…

3 heures ago

Fiche Méthode de La Tenue de Registres – Fiche Pratique

La tenue de registres est une méthode essentielle pour organiser et gérer des informations de…

16 heures ago

This website uses cookies.