Taille tableau C - Évitez les erreurs courantes et codez mieux

Noël Besnard .

24 février 2026

Tableau des codes de statut HTTP : 1xx informatif, 2xx succès, 3xx redirection, 4xx erreur client, 5xx erreur serveur.

La question de la taille d'un tableau en C revient dès qu’il faut parcourir, valider ou transmettre des données. Le piège, c’est que la bonne réponse dépend du contexte: tableau statique, paramètre de fonction, chaîne de caractères ou mémoire allouée dynamiquement. Je vais aller droit au point avec les méthodes fiables, les cas qui trompent même les développeurs expérimentés et la façon la plus propre de structurer ce calcul.

Les points essentiels pour lire la taille d’un tableau sans piège

  • `sizeof(tab) / sizeof(tab[0])` donne le nombre d’éléments seulement si `tab` est un vrai tableau dans le même scope.
  • `sizeof` renvoie des octets, pas des éléments.
  • Dans une fonction, un tableau reçu en paramètre se comporte comme un pointeur, donc sa taille réelle n’est plus disponible.
  • Pour un tableau dynamique, il faut stocker la longueur séparément.
  • Pour une chaîne C, `strlen` mesure la longueur de texte avant le `\0`, pas la capacité du tableau.
  • Avec un tableau 2D, il faut raisonner en lignes et en colonnes, pas seulement en taille totale.

Pourquoi `sizeof` donne la bonne valeur sur un vrai tableau

Dans un tableau déclaré comme objet local ou global, la méthode la plus simple reste la plus solide: diviser la taille totale en octets par la taille d’un élément. C’est exactement ce que fait `sizeof(tab) / sizeof(tab[0])`.

#include 

int main(void) {
    int notes[] = {12, 15, 9, 18, 14};
    size_t n = sizeof(notes) / sizeof(notes[0]);

    printf("Nombre d'éléments : %zu\n", n);
    return 0;
}

Ici, `sizeof(notes)` mesure tout le bloc mémoire occupé par le tableau, tandis que `sizeof(notes[0])` mesure un seul `int`. Le résultat est donc le nombre d’éléments, et non un volume en octets. C’est la formule que je recommande dans 90 % des cas simples, parce qu’elle reste correcte même si le type des éléments change ensuite. La limite apparaît dès qu’on sort du scope du tableau, et c’est là que beaucoup de code casse.

Le bon réflexe, c’est donc de distinguer taille en octets et nombre d’éléments. Une fois ce point clair, on peut regarder pourquoi la règle cesse de fonctionner au premier passage en fonction.

Pourquoi `sizeof` cesse d’être fiable dans une fonction

Illustration montrant que la taille d'un pointeur en C est constante (4 octets) pour char*, int* et struct*, indépendamment du type de données pointé.

En C, quand on passe un tableau à une fonction, il subit une conversion implicite vers un pointeur sur son premier élément. Autrement dit, la fonction ne reçoit pas le tableau complet, mais seulement une adresse. C’est pour cela que `sizeof(tab)` dans la fonction ne renvoie plus la taille du tableau, mais celle du pointeur.

#include 

void afficher_taille(int tab[]) {
    printf("%zu\n", sizeof(tab)); /* taille du pointeur, pas du tableau */
}

int main(void) {
    int a[] = {1, 2, 3, 4};
    afficher_taille(a);
    return 0;
}

Ce point est fondamental: dans une signature de fonction, `int tab[]` et `int *tab` reviennent au même pour le paramètre. Le tableau a perdu son information de longueur. Je vois souvent ce bug dans des fonctions utilitaires qui veulent “deviner” la taille d’un buffer, alors qu’elles n’en ont tout simplement pas les moyens.

Situation Ce que voit `sizeof` Bonne pratique
Tableau local `int a[10]` La taille totale du tableau Utiliser `sizeof(a) / sizeof(a[0])`
Paramètre `int a[]` dans une fonction La taille d’un pointeur Passer aussi la longueur en paramètre
Tableau dynamique `malloc` La taille du pointeur Conserver la taille dans une variable ou une structure

La conséquence pratique est simple: si une fonction doit parcourir un tableau, elle doit recevoir le pointeur et la longueur. C’est ce contrat explicite qui évite les suppositions dangereuses.

Compter les éléments sans se tromper

Pour le nombre d’éléments, la formule canonique reste `sizeof(tab) / sizeof(tab[0])`. Je préfère cette écriture à `sizeof(tab) / sizeof(int)` parce qu’elle s’adapte automatiquement au type réel du tableau. Si le tableau passe de `int` à `double`, le code continue de fonctionner sans modification.

double mesures[] = {1.2, 3.4, 5.6, 7.8};
size_t n = sizeof(mesures) / sizeof(mesures[0]);

Il faut aussi éviter une confusion très fréquente: `strlen` ne sert pas à mesurer un tableau. Elle calcule la longueur d’une chaîne C, donc le nombre de caractères avant le caractère nul `'\0'`. C’est utile pour du texte, pas pour un tableau d’entiers, de flottants ou de structures.

  • `sizeof(tab)` mesure des octets.
  • `sizeof(tab[0])` mesure un élément.
  • `sizeof(tab) / sizeof(tab[0])` donne le nombre d’éléments.
  • `strlen(tab)` compte les caractères d’une chaîne terminée par `'\0'`.

Si je devais résumer la règle en une ligne, ce serait celle-ci: on compte les éléments avec `sizeof`, on compte les caractères avec `strlen`. La suite devient plus intéressante dès qu’on quitte les tableaux d’une seule dimension.

Les tableaux 2D demandent de raisonner en lignes et en colonnes

Avec un tableau à deux dimensions, la logique reste la même, mais on doit séparer le calcul des lignes et celui des colonnes. Sur un tableau statique, les deux dimensions sont connues au moment de la compilation.

int grille[3][4];

size_t lignes = sizeof(grille) / sizeof(grille[0]);
size_t colonnes = sizeof(grille[0]) / sizeof(grille[0][0]);

Ici, `grille` contient 3 lignes de 4 entiers. Cette méthode est très utile pour boucler proprement, générer des matrices de travail ou traiter des données tabulaires en local. En revanche, elle ne survit pas au passage en fonction si on déclare le paramètre de manière trop générale.

void traiter(int grille[][4], size_t lignes) {
    for (size_t i = 0; i < lignes; ++i) {
        for (size_t j = 0; j < 4; ++j) {
            /* ... */
        }
    }
}

Le point à retenir est net: dans une fonction, la dimension des colonnes doit souvent rester connue, alors que le nombre de lignes peut être transmis séparément. Si vous travaillez avec une matrice aplatie, par exemple un buffer `rows * cols`, il faut alors stocker les deux dimensions et indexer manuellement avec `i * cols + j`.

Quand la mémoire est dynamique, la taille doit voyager avec les données

Avec `malloc`, `calloc` ou `realloc`, on ne parle plus d’un tableau statique mais d’une zone mémoire allouée dynamiquement. Le langage ne conserve pas automatiquement le nombre d’éléments associés au pointeur. Je considère donc qu’un buffer dynamique sans longueur explicite est un mauvais contrat d’API.

#include 

typedef struct {
    int *data;
    size_t size;
} IntBuffer;

Cette approche est plus lisible qu’un pointeur isolé, parce qu’elle force le code appelant à gérer la taille. Elle aide aussi à sécuriser les parcours et les réallocations. Quand le buffer grossit ou rétrécit, on met à jour la valeur `size` au même endroit, au lieu de la recomposer à partir d’un pointeur qui ne sait rien.

Dans des projets plus avancés, on peut aussi encapsuler les données dans une structure plus riche, avec capacité, longueur utile et éventuellement espace réservé. C’est souvent mieux qu’un simple tableau brut dès que le code devient partageable entre plusieurs modules. Et c’est justement là que les erreurs de taille commencent à coûter cher.

Les erreurs que je corrige le plus souvent

Les bugs liés à la taille d’un tableau sont rarement spectaculaires au début. Ils se cachent derrière un parcours incomplet, un dépassement de limite ou une valeur absurde affichée en débogage. Je revois toujours les mêmes erreurs, avec les mêmes causes.

Erreur Pourquoi elle casse Ce qu’il faut faire
Utiliser `sizeof(ptr)` comme taille d’un tableau Le pointeur n’est pas le tableau Conserver la longueur séparément
Employer `strlen` sur un tableau non textuel `strlen` s’arrête à `'\0'` Utiliser `sizeof` pour un vrai tableau
Coder une longueur en dur Le tableau évolue, la constante oublie de suivre Calculer la taille automatiquement quand c’est possible
Oublier `size_t` Le type de taille le plus adapté est signé ou tronqué selon le contexte Utiliser `size_t` pour les tailles et indices de parcours

Je fais aussi attention aux macros “magiques” censées déduire la taille à la place du programmeur. Elles peuvent fonctionner sur un tableau local, mais elles deviennent vite trompeuses si on leur passe un pointeur. À mes yeux, une règle simple et explicite reste plus robuste qu’une astuce trop automatique.

La méthode que j’utilise selon le cas réel

Si je dois donner une réponse courte et exploitable, je la formule ainsi: le tableau statique se mesure avec `sizeof`, le tableau passé en fonction se transmet avec sa taille, et le tableau dynamique garde sa longueur à côté de ses données. C’est la seule logique qui reste fiable dans un code qui évolue.

  • Tableau local ou global: `sizeof(tab) / sizeof(tab[0])`.
  • Tableau reçu par une fonction: `tab` + `size_t n`.
  • Tableau 2D statique: calculer lignes et colonnes séparément.
  • Chaîne C: `strlen` uniquement pour la longueur textuelle.
  • Mémoire dynamique: stocker la taille dans une structure ou une variable dédiée.

En pratique, je garde une règle de rédaction très simple pour le code C: ne jamais laisser une fonction “deviner” la taille d’un buffer qu’on lui a déjà fait perdre en route. C’est moins élégant qu’un calcul implicite, mais infiniment plus sûr quand le projet grossit et que plusieurs personnes touchent au même code.

Questions fréquentes

Utilisez `sizeof(monTableau) / sizeof(monTableau[0])`. Cette formule calcule le nombre d'éléments en divisant la taille totale du tableau en octets par la taille d'un seul élément, s'adaptant automatiquement au type.
Lorsqu'un tableau est passé à une fonction, il est converti en un pointeur vers son premier élément. `sizeof` renvoie alors la taille de ce pointeur (généralement 4 ou 8 octets), et non la taille réelle du tableau. Il faut passer la taille séparément.
`sizeof` mesure la taille en octets d'une variable ou d'un type, ou le nombre d'éléments pour un tableau statique. `strlen` calcule la longueur d'une chaîne de caractères C, c'est-à-dire le nombre de caractères avant le terminateur nul `'\0'`. N'utilisez pas `strlen` sur un tableau qui n'est pas une chaîne.
Pour un tableau alloué dynamiquement, le langage ne conserve pas sa taille. Vous devez stocker cette information dans une variable séparée, souvent au sein d'une structure personnalisée avec le pointeur vers les données, afin de ne pas la perdre.
Pour un tableau `int grille[LIGNES][COLONNES]`, le nombre de lignes est `sizeof(grille) / sizeof(grille[0])` et le nombre de colonnes est `sizeof(grille[0]) / sizeof(grille[0][0])`. Dans une fonction, la dimension des colonnes doit souvent être connue.

Évaluer l'article

Moyenne: 0.0 / 5 · 0 évaluations

Tags

taille d'un tableau en c mesurer taille tableau c fonction sizeof tableau dynamique c
Autor Noël Besnard
Noël Besnard
Je suis Noël Besnard, un analyste de l'industrie passionné par les domaines de la technologie, notamment le web, l'intelligence artificielle, les réseaux et la sécurité. Avec plus de dix ans d'expérience dans l'analyse des tendances du marché technologique, j'ai acquis une expertise approfondie qui me permet d'explorer les innovations et les défis auxquels notre monde numérique est confronté. Mon approche consiste à simplifier des données complexes et à fournir une analyse objective, ce qui me permet de rendre les sujets techniques accessibles à tous. Je m'engage à offrir des informations précises et à jour, en vérifiant rigoureusement les faits pour garantir la fiabilité de chaque article que je publie. Mon objectif est d'aider les lecteurs à naviguer dans cet univers en constante évolution, en leur fournissant les outils nécessaires pour comprendre les enjeux technologiques contemporains.

Commentaires (0)

Ajouter un commentaire