Initialiser un tableau d'entiers

Programmation -  
[Dal] Messages postés 6122 Date d'inscription   Statut Contributeur Dernière intervention   -
Bonsoir
Je voulais demander comment on initialise un tableau d'entier passé en paramètre dans une fonction..

3 réponses

  1. Dalfab Messages postés 638 Date d'inscription   Statut Membre Dernière intervention   102
     
    Bonjour,

    L'initialisation, c'est la première chose à faire quand une variable est instanciée, c'est donc forcément fait avant de passer le tableau en paramètre!

    A moins que ton souhait ne soit de modifier les données du tableau, dans ce cas ça se fait comme d'habitude. La chose à savoir c'est que la taille du tableau n'est pas transmise à la fonction, et comme on en a presque toujours besoin, il te faut la transmettre via un paramètre supplémentaire. En fait seule l'adresse du premier élément est effectivement transmise, mais le paramètre reçu s'utilise comme si c'était un nom de tableau.

    Ou ton problème est : que faut-il écrire pour passer un tableau en paramètre? c'est tout simplement le nom du tableau.

    Ou autre? Et si tu donnais un exemple pour que l'on comprenne mieux!
    0
  2. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 940
     
    Bonjour,

    Si j'ai bien compris, ce bout de code devrait répondre à ta question :

    Code
    #include <stdio.h>
    #include <stdlib.h>
    
    void print_tab(const int * tab, size_t size) {
        printf("[");
        for (size_t i = 0; i < size; i++) {
            printf(" %d", tab[i]);
        }
        printf(" ]\n");
    }
    
    void init_tab(int * tab, size_t size) {
        for (size_t i = 0; i < size; i++) {
            tab[i] = 10 * i;
        }   
    }
    
    int main(int argc, char **argv) {
        size_t size = 10;
        int * tab = (int *) malloc(sizeof(int) * size);
        if (!tab) {
            fprintf(stderr, "Pas assez de mémoire\n");
            return 1;
        }
        init_tab(tab, size);
        print_tab(tab, size);
        free(tab);
        return 0;
    }


    Résultat

    [ 0 10 20 30 40 50 60 70 80 90 ]


    Quelques rappels sur les pointeurs
    • print_tab
      ne nécessite qu'un accès un lecture seule sur le tableau. Il est donc préférable de l'indiquer avec le mot clé
      const
      . Ce n'est évidemment pas le cas de
      init_tab
      .
    • La fonction
      init_tab
      peut modifier le tableau, car ici
      tab
      une adresse. Lors de l'appel de
      init_tab
      , appeler
      init_tab(tab)
      recopie l'adresse stockée dans
      tab
      dans la pile, et cette adresse correspond toujours au début du bloc de 10 entiers alloué dans
      main
      . Ainsi, on modifie bien les 10 entiers alloués dans
      main
      .
    • Si on voulait écrire une fonction
      init_int
      qui modifie un entier, on pourrait être tenté d'écrire
      void init_int(int x)
      . Ça ne marcherait pas : à cause de cette histoire de recopie en pile,
      init_int
      modifierait la recopie de l'entier dans la pile, mais pas l'entier du
      main
      . Pour corriger ce problème, il faut faire un passage par pointeur : on doit passer à
      init_int
      l'adresse de cet entier (qui sera recopiée en pile, mais qui désignera bien le début du bloc qui contient notre entier déclaré dans
      main
      ). La fonction
      init_int
      est donc de la forme
      void init_int(int *px)
      et son appel de la forme
      init_int(&x)
      .


    Bonne chance
    0
  3. [Dal] Messages postés 6122 Date d'inscription   Statut Contributeur Dernière intervention   1 108
     
    Si on veut initialiser un tableau d'entiers alloué sur la pile à 0, on peut le faire lors de la déclaration, ainsi :

    int tableau[92] = { 0 };


    Si on a besoin, après avoir déclaré et utilisé le tableau, de le réinitialiser à 0 de nouveau, on peut utiliser l'instruction memset, qui permet de remplir des bytes d'une zone mémoire avec une valeur (ici 0) :

    memset(tableau, 0, sizeof(int) * 92);


    Si le "tableau" est en fait un espace mémoire alloué sur le tas, on peut le mettre à 0 lors de l'allocation, en utilisant calloc, au lieu de malloc :

    int * tableau;
    tableau = calloc(92, sizeof(int));
    if (!tableau) {
        /* TODO: gérer l'erreur d'allocation */
    }


    L'instruction memset peut aussi être utilisée pour mettre à 0 un espace mémoire alloué sur le tas, comme présenté ci-dessus, si on a besoin de le réinitialiser.

    Bref, créer une fonction ne se justifie pas toujours, pour initialiser un tableau d'entiers à 0.

    Si on doit créer une fonction pour initialiser un tableau d'entiers, parce qu'on a des besoins particuliers, ou parce qu'on aime bien faire des fonctions, il faut procéder comme indiqué par mamiemando, en passant en paramètre l'adresse du tableau et la taille du tableau, car cette dernière information sur la taille est une information perdue lors du passage du tableau, car le C passe en fait seulement l'adresse vers son premier élément et la fonction n'a aucun moyen de déterminer sa taille si on ne la transmet pas.

    Dal

    N.B. : j'ai changé le titre du post, parce que "Programmation language C" n'était vraiment pas explicite sur la nature de la question
    0