IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Besoin d'une explication Mode de passage de paramètre


Sujet :

C

  1. #1
    Candidat au Club
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2016
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Tunisie

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Janvier 2016
    Messages : 2
    Points : 4
    Points
    4
    Par défaut Besoin d'une explication Mode de passage de paramètre
    Bonjour,
    Je tente de rédiger un petit fascicule de TP sur le langage C pour débutant.
    Je suis tombé sur un point que je n'arrive pas à expliquer.

    Supposant que l'on désire écrire une procédure qui incrémente la valeur du paramètre en entrée.
    Tout le monde serait d'accord à dire que le mode de passage du paramètre doit être par adresse (pointeur)
    cela afin de modifier réellement le contenu de la variable du programme appelant et non sa copie. Ce qui donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    void incremente_val( int *v )
    {
    *v=*v+1;
    }
     
     
     int main(void)
    {
       int x ;
       x=3;
       incremente_val(&x);
     //x vaut maintenant 4   
       return 0;
    }
    Nous avons donc passé l'adresse de x en paramètre à la fonction incremente_val, et celle-ci incrémente le contenu de l'adresse pointée par le paramètre.
    Jusqu'ici tout se passe bien.

    Maintenant, supposons que l'on désire créer une procédure qui n'incrémente pas une valeur mais toutes les valeurs d'un tableau de 5 éléments.
    Je pensais que l'on devait procéder de la même manière à la seule différence que la procédure devra prendre l'adresse du tableau et non pas d'une variable scalaire.
    Cependant, j'ai constaté que si je ne précise pas que le mode de passage du paramètre tableau est par adresse, cela fonctionne quand même !
    dans le code ci-dessous, le tableau a bien été modifié au niveau du main sans qu'il soit passé par adresse dans la procédure ?!

    Dois-je en déduire que lorsqu'un paramètre de type tableau est passé en paramètre à une procédure, cette dernière considère explicitement le paramètre comme étant l'adresse du tableau?


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
     
    #define X 4
     
    void incremente_tab( int tab[X] )
    {
       int i,j;
       for(i=0; i<X; i++)
       {
              tab[i]++;
          }
    }
     
    int main(void)
    {
       int tab1[X];
          int i;
     
     
     
    for(i=0; i<X; i++)
       {
              tab1[i] = 1;
          }
     
       incremente_tab(tab1);
    //je constate ici que la tableau tab1 a bien été modifié alors que le passage ne s'est pas fait par adresse
     
     
       return 0;
    }

  2. #2
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Les tableaux sont la seule exception (si je ne dis pas de bêtise) du passage de paramètres en C : ils sont passés par référence et non par valeur comme le sont les autres types.

    Cela permet notamment d'obtenir une équivalence entre la signature de ta fonction et void incremente_tab(int *tab) - ou plus exactement void incremente_tab(int *const tab) - où tab est dégénéré en pointeur.

    Il est toutefois possible de passer un tableau par valeur en bidouillant un peu :
    Code tab.c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    #include <stdio.h>
     
     
    struct tab {
        int v[3];
    };
     
     
    void tab_print(const struct tab *t) {
        printf("[%d, %d, %d]\n", t->v[0], t->v[1], t->v[2]);
    }
     
    void ref_inc(struct tab *t) {
        ++(t->v[0]);
        ++(t->v[1]);
        ++(t->v[2]);
     
        printf("in ref_inc: ");
        tab_print(t);
    }
     
    void val_inc(struct tab t) {
        ++(t.v[0]);
        ++(t.v[1]);
        ++(t.v[2]);
     
        printf("in val_inc: ");
        tab_print(&t);
    }
     
     
    int main(int argc, char *argv[]) {
        struct tab t = { .v = { 42, 1, -2 } };
     
        tab_print(&t);
        ref_inc(&t);
        tab_print(&t);
        val_inc(t);
        tab_print(&t);
     
        return 0;
    }

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    $ gcc -std=c11 -pedantic -Wall -Wextra tab.c
    $ ./a.out
    [42, 1, -2]
    in ref_inc: [43, 2, -1]
    [43, 2, -1]
    in val_inc: [44, 3, 0]
    [43, 2, -1]

  3. #3
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    La raison en est que le nom d'un tableau est convertible en l'adresse de son premier élément.

    Attention toute fois, la longueur du tableau n'est pas transmise avec.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  4. #4
    Candidat au Club
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2016
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Tunisie

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Janvier 2016
    Messages : 2
    Points : 4
    Points
    4
    Par défaut
    Merci à vous deux pour vos explications.
    C'est en effet plus plausible maintenant.

Discussions similaires

  1. Besoin d'une explication sur une ligne !
    Par info3licen dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 04/03/2010, 19h45
  2. Besoin d'une explication sur les pointeurs
    Par ToTo13 dans le forum C
    Réponses: 6
    Dernier message: 04/10/2008, 10h41
  3. Procédure besoin d'une explication
    Par me784 dans le forum VB.NET
    Réponses: 2
    Dernier message: 02/10/2008, 01h07
  4. Besoin d'une explication sur une "notation" de vista
    Par honeydew dans le forum Windows Vista
    Réponses: 5
    Dernier message: 22/08/2008, 17h35
  5. [GWT] Besoin d'une explication relation Ajax-GWT
    Par sboober dans le forum GWT et Vaadin
    Réponses: 3
    Dernier message: 14/09/2007, 13h45

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo