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 :

Fonctions void pour modifier des paramètres


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2012
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2012
    Messages : 6
    Par défaut Fonctions void pour modifier des paramètres
    Bonjour,
    J'aimerais savoir si on peut utiliser les fonctions void pour modifier les paramètres de la fonction main?
    Par exemple, j'ai
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    main (){
     
    int montant_joueur;
    int montant_banque;
    int montant_parie;
     
    ...
    et j'aimerais savoir si en utilisant la fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    void gagner1 (int montant_joueur,int montant_banque, int montant_parie)
    { 
         montant_joueur = montant_joueur + montant_parie;
         montant_banque = montant_banque - montant_parie;
     }
    les paramètres seront modifiés.
    Sinon est-ce que je dois utiliser une fonction int et utiliser le return?

  2. #2
    Membre confirmé
    Profil pro
    amateur
    Inscrit en
    Avril 2012
    Messages
    145
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : amateur
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Avril 2012
    Messages : 145
    Par défaut
    Citation Envoyé par shtroumpf_a_lunettes Voir le message
    [...]
    et j'aimerais savoir si en utilisant la fonction
    [...]
    les paramètres seront modifiés.
    Note: je suis moi-même en (ré)apprentissage du C. Donc prends avec distance ce que je dis là en ce qui concerne le langage, bien que du point de vue programmation ce soit sûrement pas tout-à-fait stupide.

    D'abord, pour répondre litéralement à ta question: C permet de modifier des paramètres si on passe non pas leur valeur mais un pointeur sur leur adresse. Si tu réfléchis un peu à la question, tu vas comprendre pourquoi et comment cette dernière méthode fonctionne, et peut-être aussi pourquoi et comment la première, elle, ne marche pas. (Sinon, il faut que tu étudies un peu plus près la notion de variable et aussi celle de valeur.)

    Mais le problème avec ta question n'est pas là: qu'est-ce qu'un paramètre, et qu'est-ce que ça signifie (c'est l'équivalent d'une variable en maths), et qu'est-ce que ça peut signifier de le mofifier? Si des éléments dans ton programme (ou plutôt ton modèle à exprimer) décrivent quelque chose, et qu'en plus plus ils sont susceptibles de changer, c'est que ces éléments ne sont pas des paramètres proprement dits, mais des éléments de la description du "monde" (le monde logiciel fictif de ton programme). Dans ce cas, il est nécessaire de les modéliser clairement comme cela, comme des éléments de la description du monde. Et en général (sauf cas hyper simple), ça passe par créer des structures de données dont la forme reflète celle de ton monde (ou plutôt celle du modèle que tu t'en fais).

    Si ton modèle se limitait à cela, les 3 données que tu cites, et pour caricaturer un peu, j'écrirais la chose suivante:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    typedef struct {           // le type de structure de donnée
       int montant_joueur;
       int montant_banque;
       int montant_parie;
    } Etat_Du_Monde ;
     
    Etat_Du_Monde monde ;      // la chose (unique) de ce type
    A partir de là, on commence à avoir l'expression d'un modèle (à condition que tu choisisses des termes qui font sens ;-). Et faire se modifier le contenu de ce modèle commence à avoir un certain sens: si 'monde' change, c'est que le monde qu'il représente change (ce qui signifie: le temps passe), suivant la logique à l'oeuvre dans ce monde-là, que tu es justement sensé modéliser. Si tu passes l'adresse de 'monde' (ou d'un de ses éléments) à une fonction dont le rôle est le modifier, on comprend ce que tu veux dire. Surtout, on voit tout de suite que ce n'est pas un paramètre (un donnée qui influence le comportement de la fonction) mais bien un objet (au sens courant) sur lequel elle agit. Ce qui signifie que cette fonction-là n'est pas un pur utilitaire de calcul (une fonction au sens propre) mais plutôt une "action" qui exprime une partie de la logique de ce monde.
    Hum, j'espère que j'éclaircis plus les choses que je ne les embrouille ;-)

    Denis

  3. #3
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Il faut savoir ce qu'est un paramètre d'une fonction et comment fonctionne l'appel d'une fonction.

    Lors de l'appel, on spécifie les arguments d'une fonction : ce sont les valeurs qu'on souhaite transmettre à la fonction pour qu'elle puisse effectuer correctement son travail. Si en argument, on spécifie une variable, alors c'est la valeur de cette variable qui est transmise.

    La fonction reçoit ces valeurs dans des variables locales qui sont les paramètres de la fonction : lors de l'appel à la fonction, ces variables sont créées puis initialisées par les valeurs transmises en argument (elles seront détruites en sortie de la fonction comme toute variable locale).
    Toute modification d'un paramètre modifie donc la copie de l'argument, pas la variable placée en argument. La fonction n'a pas la possibilité de modifier les variables passées en argument.
    On exprime cela en disant que les paramètres sont une copie des variables passées en argument ou plus brièvement que les arguments sont passés par copie.

    Il n'y a pas d'exception à ce mécanisme.

    Or, si on veut modifier une variable, il faut savoir où elle se trouve, autrement dit connaitre son adresse. Si je veux donc qu'une fonction modifie une variable, je dois passer en argument de la fonction son adresse. Connaissant son adresse, la fonction peut modifier la variable.

    Illustration :
    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
    void gagner1 (int montant_joueur, int montant_banque, int montant_parie)
    { 
         montant_joueur = montant_joueur + montant_parie;  // modifie la variable locale montant_joueur
         montant_banque = montant_banque - montant_parie;  // modifie la variable locale montant_banque
     } 
     
    void gagner2 (int * montant_joueur, int * montant_banque, int montant_parie)
    { 
         *montant_joueur = *montant_joueur + montant_parie;  // modifie la variable d'adresse montant_joueur
         *montant_banque = *montant_banque - montant_parie;  // modifie la variable d'adresse montant_banque
     }
    ....
    int m_joueur = 50 ;
    int m_banque = 100 ; 
    ....
    gagner1( m_joueur, m_banque, 10);
    //  m_joueur et m_banque n'ont pas changé de valeur (50 et 100).
    gagner2( &m_joueur, &m_banque, 10);  // on passe l'adresse des variables à modifier
    //  m_joueur et m_banque ont changé de valeur (60 et 90).

  4. #4
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    Waouh ! Après une soirée arrosée, denispir devient philosophe

    on voit tout de suite que ce n'est pas un paramètre (un donnée qui influence le comportement de la fonction) mais bien un objet (au sens courant)
    Tu raisonnes trop en programmation orientée objet. C'est cohérent avec le fait de passer une structure qui représente le monde. Les structures s'est bien mais C est langage où tu ne cherches pas forcément à tout représenter en terme de classes / structures. Il faut en utiliser mais pas forcément tout représenter avec des structures.


    Comme l'a dit Diogene, le passage des paramètres à une fonction en C se fait par copie. Les variables passées en paramètres sont copiées dans des variables locales à la fonction.
    - si tu passes directement la variable, il est évident que tu ne peux pas la modifier puisque la fonction travaille sur la copie et que elle ne sait pas comment accéder à la variable originale.
    - si tu passes un pointeur sur cette variable (le pointeur contient l'adresse de celle-ci), ce pointeur est copié et cette copie contient l'adresse de la variable que tu souhaites modifier. Comme tu sais comment y accéder dans la fonction, tu peux la modifier.

  5. #5
    Membre confirmé
    Profil pro
    amateur
    Inscrit en
    Avril 2012
    Messages
    145
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : amateur
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Avril 2012
    Messages : 145
    Par défaut
    Citation Envoyé par Bktero Voir le message
    Waouh ! Après une soirée arrosée, denispir devient philosophe


    Tu raisonnes trop en programmation orientée objet. C'est cohérent avec le fait de passer une structure qui représente le monde. Les structures s'est bien mais C est langage où tu ne cherches pas forcément à tout représenter en terme de classes / structures. Il faut en utiliser mais pas forcément tout représenter avec des structures.
    Tu as tort, là, dans l'interprétation de mes propos. Et d'ailleurs j'ai pris la précaution de dire "un objet (au sens courant) sur lequel elle agit" précisément pour éviter les connotations systématiques de la programmation objet qui, à mon avis, introduit plus de confusion qu'elle n'en enlève.
    On est obligé d'utiliser des mots comme "objet" car une langue naturelle a un vocabulaire limité; et ce terme n'appartient pas à la POO, ils l'ont pas acheté ou breveté ;-). Tu me donnes le droit de l'employer, dis?

    J'ai pris une structure parce que c'est simple et prédéfini en C et parce que ça permettait de stocker les 3 données. Mais ç'aurait pu être n'importe quoi y compris laisser les 3 variable "volantes" (mais alors on perd l'occasion d'organiser le monde logiciel d'une façon qui reflète son sens).

    Pour illustrer mes propos voici un exemple logiciel mis en // avec une situation concrète: un chantier de peinture que tu diriges.
    Si tu dis "peins ce mur avec ce rouge-là, stp", la couleur rouge est ici une simple info, c'est-à-dire une donnée pure, au sens propre. Pour la fonction qui reçoit ça, c'est bien un paramètre, un élément de donnée qui va influencer son opération. Il n' y aucun sens à modifier ce paramètre, ce serait illogique (par sa nature même de paramètre) et si on le fait malgré tout (admettons que la couleur soit passée par ref pour l'eficacité), alors des bugs attendent de nous sauter dessus, même si on le fait intentionnellement, en pleine conscience. Parce qu'il y a un conflit sémantique entre la nature de paramètre et le fait d'opérer dessus, au lieu d'opérer avec.
    Si tu dis "rajoute de l'ocre jaune dans cette peinture-là", alors là les choses et leur sens sont différent. La fonction, outre un info de couleur, reçoit une source de couleur (le pot de peinture), ce qui est bien autre chose. C'est un objet au sens courant, et aussi bien dan sle monde concret de mon illustration que dan sle monde fictif du logiciel qui là modélise. Le pot n'est pas un paramètre, c'est l'objet sur lequel opère la fonction. (*) Le terme objet est ici dans son sens courant, bien qu'on puisse y voir, d'une façon plutôt cohérente d'ailleurs, le sens linguistique ou même philosopĥique (ce sur quoi porte ta pensée).

    J'espère que je suis clair. Il n'y a pas de POO, là, il y a de la sémantique. Le pot de peinture est un objet du fait de son sens, rien d'autre. J'essaie de comprendre le sens des choses, en programmation ( et de transmettre le peu que j'ai compris là où ça fait sens).
    Le problème avec la POO est justement qu'ils nomment objets des choses qui sont des pures données (comme la couleur dans mes deux exemples), sous prétexte par exemple que ce sont des données complexes (3 ou 4 composantes suivant l'espace de couleurs chosi). La POO entretient et accroît (à cause du terme "objet") la confusion entre les données proprement dites et les objets (ou choses) qui sont éléments dela description su monde.

    (*) D'aileurs le terme de "fonction" est incorrect lui aussi, on devrait dire une "action" pour ce genre de routine dont le but est de produire un effet, pas de computer une donnée;d'où les incompréhensions avec les supporters de la prog fonctionnelle qui eux parlent d"effets de bord" comme si c'était mal, alors que c'est justement le motif de l'action.


    Comme l'a dit Diogene, le passage des paramètres à une fonction en C se fait par copie. Les variables passées en paramètres sont copiées dans des variables locales à la fonction.
    - si tu passes directement la variable, il est évident que tu ne peux pas la modifier puisque la fonction travaille sur la copie et que elle ne sait pas comment accéder à la variable originale.
    - si tu passes un pointeur sur cette variable (le pointeur contient l'adresse de celle-ci), ce pointeur est copié et cette copie contient l'adresse de la variable que tu souhaites modifier. Comme tu sais comment y accéder dans la fonction, tu peux la modifier.
    C'est très juste et très clair. Mais pas contradictoire, en fait plutôt ohérent, avec mes propos (ou alors je comprends pas en quoi cela me contredit).

    denis

  6. #6
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    On est obligé d'utiliser des mots comme "objet" car une langue naturelle a un vocabulaire limité; et ce terme n'appartient pas à la POO, ils l'ont pas acheté ou breveté ;-).
    La norme (n1256) définit le terme "objet" pour le C
    3.14
    1 object
    region of data storage in the execution environment, the contents of which can represent values
    d'où les incompréhensions avec les supporters de la prog fonctionnelle qui eux parlent d"effets de bord" comme si c'était mal, alors que c'est justement le motif de l'action.
    La notion d'effets de bords existe également mais sans aspects péjoratifs
    5.1.2.3 Program execution
    ...
    2 Accessing a volatile object, modifying an object, modifying a file, or calling a function that does any of those operations are all side effects,11) which are changes in the state of the execution environment.
    Une expression dont l'évaluation n'entraine pas d'effets de bords ne sert à rien et est inopérante.

  7. #7
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 830
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 830
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par denispir Voir le message
    Le problème avec la POO est justement qu'ils nomment objets des choses qui sont des pures données (comme la couleur dans mes deux exemples), sous prétexte par exemple que ce sont des données complexes (3 ou 4 composantes suivant l'espace de couleurs chosi). La POO entretient et accroît (à cause du terme "objet") la confusion entre les données proprement dites et les objets (ou choses) qui sont éléments dela description su monde.
    Pourtant le terme "objet" en POO a été créé pour représenter "au mieux" les objets du monde réel et peut-être que ceux qui font la confusion ont oublié cette volonté "initiale" de la POO.
    De plus la complexité de l'objet dépend de son public. Pour le peintre qui doit peindre son mur en rouge carmin le "rouge carmin" n'est qu'un élément simple issu d'un pot choisi sur l'étalage parmi d'autres mais pour le fabriquant de peinture qui doit créer cette nuance de rouge virant sur le violet, la chose sera éminemment plus complexe et nécessitera peut-être un objet dédié...


    Citation Envoyé par diogene Voir le message
    Une expression dont l'évaluation n'entraine pas d'effets de bords ne sert à rien et est inopérante.
    Excuse-moi mais là je ne comprends pas trop. Pour moi, si j'écris j=i+1 j'ai l'impression qu'il y a 2 actions
    • l'expression qui évalue i+1
    • la copie du résultat de cette expression dans j

    Pour moi il n'y a pas eu d'effet de bord mais mon expression a servi a quelque chose. Idem si j'écris j=carre(i) avec carre() définit ailleurs...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

Discussions similaires

  1. Réponses: 7
    Dernier message: 16/10/2014, 00h25
  2. Réponses: 1
    Dernier message: 27/11/2008, 10h55
  3. utiliser une fonction VOID pour des blocs relationnels ?
    Par ctobini dans le forum PostgreSQL
    Réponses: 3
    Dernier message: 11/09/2006, 16h16
  4. Réponses: 24
    Dernier message: 07/12/2005, 10h37
  5. Réponses: 3
    Dernier message: 02/09/2002, 18h49

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