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 :

Fonction et pointeur


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Étudiant
    Inscrit en
    Avril 2006
    Messages
    252
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2006
    Messages : 252
    Par défaut Fonction et pointeur
    Bonjour à tous!

    Voici mon code:

    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
    31
    32
    33
    34
     
    #include <stdio.h>
     
    #define NB_PARAM 3
    int i;
    unsigned char *parametres[NB_PARAM]={"height", "width", "duree"};
     
    unsigned char commande[255]="";
     
    /*
    Cette fontion permet de vérifier qu'il y a bien le nombre de paramètres nécessaires
    à l'initialisation de la vidéo
    */
    void test_parametres(char *a, char *b){
    	if(b==NULL){
    		printf("Erreur de chargement sur %s\n", a);}
    	else{
    		printf("passage de la valeur\n");
    		printf("a:%s\n",a);
    		printf("b:%s\n",b);	
    		a=b;
    	}
    }
     
    /*
    Fonction main qui permet de créer un fichier vidéo
    */
    int main(int argc,char *argv[]){
     
    for(i=0; i<NB_PARAM; i++){
    test_parametres(parametres[i],argv[i+1]);
    printf("parametre %d: %s\n", i, parametres[i]);
    }
    }
    Ma question est assez simple, lorsque je faisais dans le main ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    parametres[0]=argv[2];
    printf("hauteur: %s \n", parametres[0]);
    J'obtenais la valeur du paramètre rentré sans aucun souci.
    J'ai voulu créer une fonction (afin de rendre mon code plus claire et plus facilement testable), lorsque j'exécute le programme, je n'obtiens plus la valeur rentrée en paramètre,
    mais la valeur initiale (par exemple "height").

    Je ne comprends pas parce que j'ai l'impression (fausse...) que je fais exactement la même chose..

    Plutôt que de bidouiller, je voudrais comprendre où est mon erreur..
    Merci
    F.

  2. #2
    Membre Expert
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Par défaut
    Citation Envoyé par Flophx
    J'ai voulu créer une fonction (afin de rendre mon code plus claire et plus facilement testable), lorsque j'exécute le programme, je n'obtiens plus la valeur rentrée en paramètre, mais la valeur initiale (par exemple "height").
    La saisie de la nouvelle valeur se fait dans la fonction ? N'oublie pas que le C passe les arguments de fonction par valeur (i.e. copie de la variable passee en argument). Si tu veux modifier la valeur d'une variable a l'interieur d'une fonction, il faut passer son adresse.
    Mauvais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    void f(int a)
    {
      a = 2;
    }
    ...
    int b = 3;
    f(b);
    /* b vaut toujours 3 */
    Bon:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    void f(int *a)
    {
      *a = 2;
    }
    ...
    int b = 3;
    f(&b);
    /* b vaut maintenant 2 */

  3. #3
    Membre émérite Avatar de stephl
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2007
    Messages
    643
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2007
    Messages : 643
    Par défaut
    Tel que vous l'avez écrit, c'est le pointeur local à la fonction test_parametres() qui est modifié, pas celui de main(). Il faut changer de la manière suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    void test_parametres(char **a,char *b)
     {
     if (b==NULL) printf("Erreur de chargement sur %s\n",*a);
     else
      {
      /*...*/
      *a=b;
      }
     }
     
     
    dans main:
    test_parametres(&parametres[i],argv[i+1]);

  4. #4
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    1. Euh... C'est dans ton a=b que tu espérais faire le changement ?
    2. Je pense que tu devrais utiliser des const char *, et sans doute aussi éviter de jouer avec leur signe.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Membre éclairé
    Profil pro
    Étudiant
    Inscrit en
    Avril 2006
    Messages
    252
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2006
    Messages : 252
    Par défaut
    Euh... C'est dans ton a=b que tu espérais faire le changement ?
    Oui et non, dans la mesure où j'avais bien vu que c'était la valeur qui était effectivement passée en paramètre, mais en passant l'adresse de la variable à modifier je me susi retrouvé face à cette erreur:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
     passing argument 1 of ‘test_parametres’ from incompatible pointer type
    Et là, ne sachant pas ce qui cloche, je demande!

  6. #6
    Membre éclairé
    Profil pro
    Étudiant
    Inscrit en
    Avril 2006
    Messages
    252
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2006
    Messages : 252
    Par défaut
    Et de nouveau, en utilisant une indirection supplémentaire, j'ai:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
     passing argument 1 of ‘test_parametres’ from incompatible pointer type
    avec ce code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    test_parametres(&parametres[i],argv[i+1]);
    et

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    void test_parametres(char **a, char *b){
    	if(b==NULL){
    		printf("Erreur de chargement sur %s\n", *a);}
    	else{
    		printf("passage de la valeur\n");
    		printf("a:%s\n",*a);
    		printf("b:%s\n",b);	
    		*a=b;
    	}

  7. #7
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    As-tu essayé avec?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    void test_parametres(char const **a, char const *b){
        if (a != NULL)
        {
    	if(b == NULL){
    		printf("Erreur de chargement sur %s\n", *a);
            }
    	else {
    		printf("passage de la valeur\n");
    		printf("*a:%s\n", *a);
    		printf("*b:%s\n", b);	
    		*a = b;
    	}
        }
    }
    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  8. #8
    Membre éclairé
    Profil pro
    Étudiant
    Inscrit en
    Avril 2006
    Messages
    252
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2006
    Messages : 252
    Par défaut
    Bien, effectivement en changeant tous les
    par

    Ca marche, mais je comprends pas pourquoi l'erreur provenait en partie de là....

  9. #9
    Membre émérite Avatar de stephl
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2007
    Messages
    643
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2007
    Messages : 643
    Par défaut
    Normalement, ce sont juste des avertissements (warning) pour avoir mélangé pointeurs sur char, unsigned char, et const char. On peut passer outre avec un cast, mais le mieux est de se décider entre char et unsigned char.

  10. #10
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Citation Envoyé par Flophx
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    void test_parametres(char *a, char *b){
    	if(b==NULL){
    		printf("Erreur de chargement sur %s\n", a);}
    	else{
    		printf("passage de la valeur\n");
    		printf("a:%s\n",a);
    		printf("b:%s\n",b);	
    		a=b;
    	}
    }
    Lorsque tu écris:
    Tu fais pointer a sur la même adresse que b. Mais n'oublie pas qu'en C, le passage des arguments se fait toujours par valeur, c'est à dire que a est initialisé avec une copie de la valeur contenue dans parametres[i] et b est initialisé avec une copie de la valeur contenue dans argv[i+1].

    Lorsque tu modifie la valeur de a, tu ne modifie pas la valeur de parametres[i], car tu travaille sur une copie. Pour résoudre ton problème, il te faut un niveau d'indirection supplémentaire:
    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
    #include <stdio.h>
    #define NB_PARAM 3
     
    void test_parametres(char **a, char *b){
        if (a != NULL)
        {
    	if(b == NULL){
    		printf("Erreur de chargement sur %s\n", *a);
            }
    	else {
    		printf("passage de la valeur\n");
    		printf("*a:%s\n", *a);
    		printf("*b:%s\n", b);	
    		*a = b;
    	}
        }
    }
     
    int main(int argc,char *argv[]){
        int i;
        char const*parametres[NB_PARAM] = {"height", "width", "duree"};
        char commande[255] = "";
     
        for(i = 0; i < NB_PARAM; i++){
            test_parametres(parametres + i, argv[i+1]);
            printf("parametre %d: %s\n", i, parametres[i]);
        }
        return EXIT_SUCCESS;
    }
    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  11. #11
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    char const ** ?
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Fonction, structure, pointeurs et scanf
    Par exhortae dans le forum C
    Réponses: 13
    Dernier message: 27/02/2007, 17h31
  2. Passage de tableau à une fonction par pointeur
    Par progfou dans le forum C++
    Réponses: 15
    Dernier message: 23/02/2007, 11h45
  3. Réponses: 8
    Dernier message: 10/03/2006, 17h28
  4. C++ Problème de fonctions et pointeurs
    Par zmatz dans le forum C++
    Réponses: 3
    Dernier message: 01/10/2005, 16h20
  5. Réponses: 10
    Dernier message: 03/02/2005, 13h09

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