print · rss · source

< Portée des données au sein d'un programme | TutoCFrench | Chaînes de caractères >


Les tableaux

Notions :

  • définition
  • initialisation, affectation
  • indices de 0 à n-1
  • débordements
  • opérateur crochets []
  • tableaux à n dimensions

Un tableau permet de regrouper plusieurs données du même type. Nous avions vu que les variables pouvaient être comparées à des boites. De façon similaire, un tableau peut être vu comme une commode à tiroirs, chaque tiroir pouvant stocker une donnée :

Déclaration et initialisation

Les tableaux en C se déclarent avec l'opérateur [] :

/* declaration d'un tableau de 10 caractères */
char tab[10];

Il est possible d'initialiser un tableau lors de sa déclaration en mettant les valeurs du tableau entre accolades :

/* declaration et initialisation d'un tableau de 3 entiers */
int a[3] = {1, -1, 0};

Quand on initialise un tableau au moment de sa déclaration, on n'est pas obligé de spécifier sa taille, celle-ci est automatiquement calculée par le compilateur :

/* declaration et initialisation d'un tableau de 4 caracteres */
char msg[] = {'a', 'b', 'c', '\0'}; 

Accèder à une valeur

On accède à un élément d'un tableau grâce à l'opérateur crochets []. Le premier élément a l'indice 0 et le dernier l'indice n-1. Le nième élément de tab[] s'écrit donc tab[n-1] :

int t[5] = {1, 2, 4, 8, 16};
printf("%d", t[0]); /* Affiche le 1er element de t[] */
printf("%d", t[2]); /* Affiche le 3e element */
printf("%d", t[4]); /* Affiche le dernier element */

Affecter des valeurs à un tableau

On peut affecter un tableau seulement élément par élément :

int tab[3];
tab[0] = 1;
tab[1] = 0;
tab[2] = 5;

Exemple d'initialisation de tous les membres d'un tableau à 0 :

int t[100];
for(i=0; i<100 ;i++) 
    t[i] = 0;

Il n'est par conséquent pas possible d'affecter directement un tableau à un autre tableau. L'affectation doit se faire là encore élément par élément :

int import[3], export[3] = {1023, 867, 29};
int i;
for (i=0; i<3; i++)
    import[i] = export[i];

De la même manière, il est incorrect d'utiliser les opérateurs de comparaison pour comparer deux tableaux. Affectation, comparaison... toutes ces opérations ne peuvent être réalisées qu'élément par élément !

L'explication de tout cela est qu'un nom de tableau utilisé dans une expression est converti en pointeur sur le premier élément de ce tableau. Ainsi, l'expression tab1 == tab2 revient à comparer les adresses en mémoire où sont implantés ces tableaux.

Les débordements

Attention, quand on affecte un élément d'un tableau, il n'y a aucun contrôle fait pour savoir si on déborde ou non du tableau. Voici un exemple de débordement :

int tab[5];
tab[8] = 1; /* debordement : les indices vont de 0 a 4 */

Une telle erreur ne sera pas repérée par le compilateur et ne se manifestera dans le meilleur des cas qu'à l'exécution par un message du type Bus error ou Segmentation fault. Dans le pire des cas, des données seront corrompues de manière aléatoire !

Passage en argument de fonctions

Le passage d'un tableau en argument d'une fonction est très particulier. Le passage du tableau en argument ne se fait pas par valeur mais par adresse (nous comprendrons mieux cette notion quand nous aurons vu les pointeurs. Ceci a beaucoup d'implications.

Déclaration et définition

L'utilisation des crochets indique qu'une fonction attend un nom de tableau en argument. Pour déclarer une fonction :

type nom(type[]);

Pour définir une fonction :

type nom(type var[], ...)
{
/* corps de la fonction */
}

Par exemple, une fonction qui prend en argument un tableau d'entiers :

void mafonction(int[]); /* le prototype */

void mafonction(int tab[]) /* la fonction */
{
    /* code de la fonction ... */
    return;
}

Attention, à aucun endroit on ne spécifie la taille du tableau ! Cela ne peut se faire qu'avec un deuxième argument passé à la fonction.

Passage en argument

Le passage en argument se fait en positionnant juste le nom du tableau :

int main()
{
    int t[6];
    mafonction(t);
    return 0;
}

Dans la fonction

Dans la fonction, on n'a aucun moyen de savoir quelle est la taille du tableau passé en argument. Pour connaître cette taille, il faut la passer en argument :

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

Un tableau est passé non par valeur mais par adresse. Cela a une implication énorme : un tableau passé en argument à une fonction peut être modifié par celle-ci !

void init_array(int t[], int n) 
{
    int i;
    for(i=0; i<n; i++) 
        t[i] = 0;
}

int main()
{
    int notes[25];
    init_array(notes, 25); /* modifie les valeurs dans 'notes' */
    show_array(notes, 25); 
    return 0;
}

Tableau en tant que valeur de retour d'une fonction

Attention, une fonction ne peut jamais renvoyer un tableau !

Exercices

1. "notes.c" : programme qui saisit les notes de 10 élèves, qui fait la moyenne des notes, puis qui affiche les notes au-dessus de la moyenne
2. "tri.c" : programme qui saisit une liste de 10 nombres, la trie puis la réaffiche.

Solutions

notes.c

#include <stdio.h>

int main()
{
    float n[10], moy = 0;
    int i;

    for (i=0; i<10; i++) {
        printf("> ");
        scanf("%f", &n[i]);
        moy += n[i];
    }
    moy = moy / 10;
    printf("moyenne = %f\n", moy);

    for (i=0; i<10; i++)
        if (n[i] > moy)
            printf("%f\n", n[i]);

    return 0;
}

tri.c

#include <stdio.h>

void tri(int[], int);

int main()
{
    int liste[10];
    int i;

    for (i=0; i<10; i++) 
        scanf("%d", &liste[i]);
    printf("ok\n");

    tri(liste, 10);

    for (i=0; i<10; i++) 
        printf("%d\n", liste[i]);

    return 0;
}

void tri(int t[], int n)
{
    int i, j;
    int tmp;

    for (i=0; i<n; i++) {
        for (j=i+1; j<n; j++)
            if (t[i] > t[j]) {
                tmp = t[j];
                t[j] = t[i];
                t[i] = tmp;
            }
    }
}

< Portée des données au sein d'un programme | TutoCFrench | Chaînes de caractères >

print · rss · source
Page last modified on February 11, 2008, at 03:40 PM