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 :

Retourner deux valeurs d'une fonction


Sujet :

C

  1. #1
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    octobre 2019
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : octobre 2019
    Messages : 6
    Points : 2
    Points
    2
    Par défaut Retourner deux valeurs d'une fonction
    Bonjour,

    Actuellement entrain d'apprendre à utiliser les pointeurs, j'essaye un exercice qui consiste à utiliser plusieurs fonctions afin de faire deux opérations élémentaires... une soustraction et une addition...

    Concrètement, le but étant d'avoir une fonction somme ne retournant rien ni aucun affichage avec 3 paramètres (les deux chiffres a additionner et une variable de stockage), une fonction soustraction qui ne retourne rien elle non plus (les deux chiffres a soustraire et une variable de stockage), une fonction calcul qui appelle les deux fonctions précédente avec 4 paramètres (cette fonction n'affiche rien ce n'est pas le but mais doit par contre retourner les deux résultats, celui de la somme et celui de la soustraction).
    Par la suite un simple scanf pour demander deux valeurs et l'appel de la fonction calc(a,b,C,D) afin de réaliser les opérations citées plus haut.

    Pour l'instant j'arrive bien à obtenir le résultat escompté, cependant avec des warnings que je n'arrive pas à régler malgré qu'il soit relativement explicite...
    Auriez vous une idée de la méthode ?
    voici le code en question :

    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
    #include <stdio.h>
     
    int somme(int a,int b, int S){
    	S=a+b;
    }
    int diff(int a,int b,int D) {
    	D=a-b;
    }
    int calc(int a,int b,int* E,int* R) {
     
    	*E=somme(a,b,E);
    	*R=diff(a,b,R);
    }
    int main() {
    	int a=0,b=0,S,D;
    	printf("Entrez la valeur de a et b\n");
    	scanf("%d%d",&a,&b);
     
    	calc(a,b,&S,&D);
    	printf("la somme de a+b = %d, la difference entre a et b est de : %d", S,D);
    }
    Avec pour résultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    main.c:3:5: note: expected ‘int’ but argument is of type ‘int *’                                                                                                    
    main.c:12:14: warning: passing argument 3 of ‘diff’ makes integer from pointer without a cast [-Wint-conversion]                                                    
    main.c:6:5: note: expected ‘int’ but argument is of type ‘int *’                                                                                                    
    Entrez la valeur de a et b                                                                                                                                          
    10                                                                                                                                                                  
    15                                                                                                                                                                  
    la somme de a+b = 25, la difference entre a et b est de : -5
    Merci d'avance : )

  2. #2
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    décembre 2015
    Messages
    1 007
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : décembre 2015
    Messages : 1 007
    Points : 5 053
    Points
    5 053
    Par défaut
    Bonjour,

    En fait ce qui manque ce sont les warnings signalant d'autres erreurs. Tu devrais activer un niveau de warning plus élevé pour les voir. Si tu ne sais pas comment dis nous quel compilateur tu utilises.
    Les problèmes que je vois :
    - fonction somme(), elle reçoit un S qu'elle n'utilise jamais en lecture (pourquoi le recevoir?)
    - fonction somme(), elle met à jour un paramètre local S alors que ce paramètre va disparaître immédiatement après! Toutes les variables locales sont détruites à la fin d'un bloc, ici ce sont S, b et a. Ici pourtant ce calcul va par la "magie" des registres processeurs rester quelque part.
    - fonction somme(), elle prétend retourner un int, mais il n'y a aucun return. C'est une grave erreur.
    - fonction diff() : les 3 même remarques.
    - fonction calc() : elle passe en 3ième paramètre de somme E qui est l'adresse d'un int. Mais la fonction somme() attendait un simple int. C'est le warning que tu as. Si tu étais en C++ ça serait une erreur grave car c'est très grave.
    - fonction calc() : elle aussi prétend retourner un int mais ne retourne rien.
    - même remarque pour R.
    - fonction main(), là tout est clair, on ne confond pas les intet les pointeurs.

    Maintenant, pourquoi ton code "marche"? C'est en effet un vrai miracle! Au final les bon nombres se retrouvent au endroit, mais c'est une simple coïncidence!

    Maintenant si l'interface de la fonction somme devenait void somme(int a, int b, int* p_s) que deviendraient toutes mes remarques, et quelle corrections seraient nécessaires?

  3. #3
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    février 2006
    Messages
    7 596
    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 : 7 596
    Points : 21 642
    Points
    21 642
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par Skz69 Voir le message
    Actuellement entrain d'apprendre à utiliser les pointeurs, j'essaye un exercice qui consiste à utiliser plusieurs fonctions afin de faire deux opérations élémentaires... une soustraction et une addition...
    Concrètement, le but étant d'avoir une fonction somme ne retournant rien ni aucun affichage avec 3 paramètres (les deux chiffres a additionner et une variable de stockage)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    int somme(int a,int b, int S){
    	S=a+b;
    }
    Donc tu es en train d'apprendre les pointeurs. Il est alors fortement probable que ton exercice te demandera d'utiliser des pointeurs. Mais tu ne les utilises pas. Fatalement il y a une incohérence.
    De plus ta fonction "somme()" modifie une variable temporaire ("S") qui sera perdue quand elle se termine. N'as-tu pas appris qu'une fonction ne pouvait en aucun cas modifier le paramètre qu'elle reçoit ? Enfin elle le peut bien entendu mais comme il disparait quand la fonction se termine c'est généralement vide de sens.

    Exemple
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void init(int s) {
        s=123;
    }
     
    int main() {
        int s=500;
        init(s);
        printf("s=%d\n", s);
    }

    Donc si ma fonction init() n'arrive pas à modifier "s", il est peu probable que ta fonction y arrive.

    Par ailleurs tu n'as pas appris à utiliser scanf() (qui, elle, bizarrement, arrive à modifier une variable qu'on lui passe) ?
    Donc réfléchis à ta façon d'appeler scanf() ce qui te permettra de modifier mon exemple pour qu'il puisse modifier "s" ce qui te permettra ensuite de créer ton addition de façon correcte.

    Citation Envoyé par Skz69 Voir le message
    le but étant d'avoir une fonction somme ne retournant rien
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int calc(int a,int b,int* E,int* R) {
     
    	*E=somme(a,b,E);
    	*R=diff(a,b,R);
    }
    Donc si ta fonction somme() ne retourne rien (et c'est son but), pourquoi tu tentes de récupérer ce qu'elle retourne ???

    Citation Envoyé par Skz69 Voir le message
    cette fonction n'affiche rien ce n'est pas le but mais doit par contre retourner les deux résultats, celui de la somme et celui de la soustraction).
    Impossible. En aucun cas une fonction ne peut retourner 2 valeurs en même temps. Et ton code ne reflète pas cet énoncé puisque ta fonction en réalité, ne retourne rien du tout.

    Donc quand ce sera clair dans ta tête sur comment doivent travailler tes différentes fonctions tu auras fait un grand pas en avant...

    Citation Envoyé par dalfab Voir le message
    Maintenant, pourquoi ton code "marche"? C'est en effet un vrai miracle! Au final les bon nombres se retrouvent au endroit, mais c'est une simple coïncidence!
    En fait je pense que la fonction calc() récupère de somme() et diff() les dernières valeurs calculées (stockées dans la pile et récupérées effectivement "par accident"). Ou alors comme les fonctions sont "int" elles retournent quand-même les dernières valeurs. Ou alors c'est cette bizarre syntaxe *S=somme(a, b, S) qui pomme complètement le compilo (quand la tartine tourne deux fois en tombant elle se retrouve quand-même du bon côté).
    C'est évidemment le pire cas qui peut se produire => avoir un code foireux qui produit le bon résultat
    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

  4. #4
    Membre confirmé

    Homme Profil pro
    Directeur de projet
    Inscrit en
    mai 2013
    Messages
    92
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : mai 2013
    Messages : 92
    Points : 540
    Points
    540
    Par défaut Pointeur et fonction
    Bonjour,

    Je pense qu'il est demandé d'écrire une fonction (en fait plutôt une procédure) qui utilise des pointeurs pour retourner des résultats (ie sans return). Peut être quelque chose comme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void SomDif(int a, int b, int *s, int *d) {
    *s = a + b;
    *d = a - b;
    }
    Cependant un passage par référence serait, me semble t-il, plus élégant, mais ce n'est qu'un exercice.

    Salutations
    Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)

  5. #5
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    février 2006
    Messages
    7 596
    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 : 7 596
    Points : 21 642
    Points
    21 642
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Guesset Voir le message
    Je pense qu'il est demandé d'écrire une fonction (en fait plutôt une procédure)
    Contrairement au Pascal, le C ne fait pas de distinction fonction/procédure. D'ailleurs pourquoi Pascal en fait ça...

    Citation Envoyé par Guesset Voir le message
    qui utilise des pointeurs pour retourner des résultats (ie sans return)
    Ca ne veut rien dire "utiliser des pointeurs pour retourner des résultats". La fonction ne retourne rien. Elle remplit des variables prévues pour recevoir les valeurs calculées.

    Citation Envoyé par Guesset Voir le message
    Peut être quelque chose comme :
    T'es pas non plus sensé donner la solution (ie règles du forum)

    Citation Envoyé par Guesset Voir le message
    Cependant un passage par référence serait, me semble t-il, plus élégant, mais ce n'est qu'un exercice.
    Et surtout le passage par références n'existe pas en C.
    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

  6. #6
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    octobre 2019
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : octobre 2019
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    Merci pour ces réponses, je vais me pencher sur toutes ces précisions.

    Concernant la solution apporter, c'est à dire que c'est ce que je fais si je ne m'abuse ? et cette solution ne convient pas du fait qu'elle fasse elle même le calcul. Ce n'est pas ce qui est demandé...
    On parle ici d'un exercice qui a 3 fonction :

    1 -> La fonction somme : qui ne retourne rien et qui a 3 paramètres.
    2 -> La fonction différence : qui retourne quelque chose cette fois (D en l’occurrence) et qui a 3 paramètres aussi
    3 -> La fonction calcul, qui utilise ces 2 fonctions pour faire les deux calculs. Cette fonction a 4 paramètres, mais ne fait aucun affichage.
    Enfin dans le main, il est demandé d'utiliser la fonction calcul afin de demander la saisie de deux entiers afin d'appeler la fonction calcul pour effectuer la somme et la différence.

    Je me rends compte que je n'avais pas été clair du tout dans mon premier message.

    Je vais me pencher sur le message de Dalfab, qui semble assez bien résumer la situation.
    Pour ce qui est de mon compilateur j'utilise clang sous débian avec Vi en éditeur...

    Ce que je viens de saisir c'est qu'en aucuns cas je ne dois déclarer mes fonctions somme et calcul en tant que "int" car en soit elle ne retourne rien, je dois donc partir sur une "void", cependant la fonction différence qui elle retourne bien un int est bien déclarer et je peux donc l'appeler dans ma fonction calcul comme ce qui suit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    void calcul(int a, int b, int* S, int D) {
              D = diff(a,b,D); // correct car diff est de type int et un return D a été rajouté.
    }
    Cependant, il est pas mal difficile selon moi avec le peu de C que j'ai dans les jambe (et le peu de programmation tout simplement, étant en cours du soir sur un cursus m2 tout en étant en activité sur un poste accès réseau qui est d'ailleurs ma formation principale...).

    Ce que je comprends en tout cas, c'est que des pointeurs devront être utilisés entre la fonction somme et calcul ainsi qu'en calcul et le main. Cependant je ne comprends vraiment pas l'intérêt en effet d'avoir une fonction somme avec 3 paramètres alors que S ne sera jamais utilisé...
    C'est un mystère pour moi d'ou ma première version de ce code.

    Je vais me remettre sur ce problème en essayant d'intégrer vos remarques Merci dans tous les cas.

  7. #7
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    février 2006
    Messages
    7 596
    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 : 7 596
    Points : 21 642
    Points
    21 642
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Skz69 Voir le message
    Concernant la solution apporter, c'est à dire que c'est ce que je fais si je ne m'abuse ?
    Pas tout à fait. Guesset fait l'addition directement dans la fonction "SomDif" tandis que toi tu tentes de récupérer l'addition depuis une autre fonction. C'est une nuance.

    Citation Envoyé par Skz69 Voir le message
    et cette solution ne convient pas du fait qu'elle fasse elle même le calcul. Ce n'est pas ce qui est demandé...
    Exact. Mais il a quand-même écrit des trucs intéressant à étudier...

    Citation Envoyé par Skz69 Voir le message
    1 -> La fonction somme : qui ne retourne rien et qui a 3 paramètres.
    Exact
    Citation Envoyé par Skz69 Voir le message
    2 -> La fonction différence : qui retourne quelque chose cette fois (D en l’occurrence) et qui a 3 paramètres aussi
    Citation Envoyé par Skz69 Voir le message
    une fonction soustraction qui ne retourne rien elle non plus
    Ca a donc changé depuis ton premier post !!!

    Citation Envoyé par Skz69 Voir le message
    Je me rends compte que je n'avais pas été clair du tout dans mon premier message.
    Sisi, c'était parfaitement clair.

    Citation Envoyé par Skz69 Voir le message
    Ce que je viens de saisir c'est qu'en aucuns cas je ne dois déclarer mes fonctions somme et calcul en tant que "int" car en soit elle ne retourne rien,
    Totalement exact

    Citation Envoyé par Skz69 Voir le message
    Cependant je ne comprends vraiment pas l'intérêt en effet d'avoir une fonction somme avec 3 paramètres alors que S ne sera jamais utilisé...
    Personne n'a jamais dit que le 3° paramètre ne serait jamais utilisé. Ce que nous avons dit, c'est que toi tu ne l'utilisais pas correctement. Je t'assure que le 3° paramètre sera bel et bien utilisé.
    Et même (petit moment de réflexion), si la fonction somme() reçoit 3 paramètres ; et que les deux premiers sont les entiers devant être additionnés ; et que ton exo traite des pointeurs ; alors il est fortement probable que le 3° paramètre sera un...

    Citation Envoyé par Skz69 Voir le message
    Je vais me remettre sur ce problème en essayant d'intégrer vos remarques
    Concentre-toi sur mon premier exemple: comment modifier init() pour qu'il modifie la variable de l'appelant. C'est la base de tout.
    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

  8. #8
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    octobre 2019
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : octobre 2019
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    Oui en effet, ça a changer depuis... une erreur de ma part au départ.

    Dans tous les cas, je reviens sur ce que tu dis Sve@r, je pense qu'on s'est mal compris, car le truc intéressent dans le poste de Guesset c'est sans doute l'utilisation de pointeur, sauf que c'est plus ou moins ce qui est fait dans mon code initial :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    int calc(int a,int b,int* E,int* R) {
     
    	*E=somme(a,b,E);
    	*R=diff(a,b,R);
    }
    int main() {
    	int a=0,b=0,S,D;
    	printf("Entrez la valeur de a et b\n");
    	scanf("%d%d",&a,&b);
     
    	calc(a,b,&S,&D);
    	printf("la somme de a+b = %d, la difference entre a et b est de : %d", S,D);
    }
    Le soucis ici c'est que l'utilisation des deux fonctions somme et diff viole toutes les règles du C (et ça je l'ai bien compris maintenant :p)

    Concernant ta question en rapport avec scanf, voici la réponse :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void init(int* s) {
        *s=123;
    }
     
    int main() {
        int s=500;
        init(&s);
        printf("s=%d\n", s);
    }
    Je pense avoir plus ou moins compris ce concept d'adresse et de valeur &X représentant l'adresse de X et *X représentant la valeur associé à l'adresse de X si je ne m'abuse ?...

    Cependant mon soucis étant également basé sur les fonctions, le passage de pointeur entre fonction etc... (en ayant eu un cours de 4h mardi, mélangeant tableau fonction et pointeur je suppose qu'il est logique que je m'embrouille un peu...)

    Dans tous les cas je vais étudier tout cela, cependant pouvez vous m'aiguiller, dois-je ici dans ce cas utiliser des pointeurs de pointeurs ? pour le passage fonction 1>2 puis 2>3 ? ou des simples pointeurs suffissent dans ce cas ?

  9. #9
    Membre confirmé

    Homme Profil pro
    Directeur de projet
    Inscrit en
    mai 2013
    Messages
    92
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : mai 2013
    Messages : 92
    Points : 540
    Points
    540
    Par défaut
    bonsoir,

    Citation Envoyé par Sve@r Voir le message
    Contrairement au Pascal, le C ne fait pas de distinction fonction/procédure. D'ailleurs pourquoi Pascal en fait ça...
    Le type void transforme une fonction en procédure même si le terme fonction continue à être utilisé en C. La différence entre fonction et procédure est essentiellement qu'une fonction peut être une RValue ce qui paraît difficile en C si elle est déclarée void.


    Citation Envoyé par Sve@r Voir le message
    Ça ne veut rien dire "utiliser des pointeurs pour retourner des résultats". La fonction ne retourne rien. Elle remplit des variables prévues pour recevoir les valeurs calculées.
    Placer un résultat à une adresse donnée me semble la définition exacte d'un retour de valeurs que ce soit via la pile ou des adresses passées en argument. C'est peut être le terme retourner qui choque en faisant penser à return ?


    Citation Envoyé par Sve@r Voir le message
    T'es pas non plus sensé donner la solution (ie règles du forum)
    Au vu des commentaires qui ont suivi il ne semble pas que ce soit le cas.

    Citation Envoyé par Sve@r Voir le message
    Et surtout le passage par références n'existe pas en C.
    C'est exact, c'est du C++.

    Salutations.
    Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)

  10. #10
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    octobre 2019
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : octobre 2019
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    Les débats faisant rage, je vois qu'il n'est pas aisé de se mettre d'accord sur ce langage...

    Dans tous les cas pour revenir sur le sujet initial, c'est que je ne comprends pas l'utilité de cet exercice du fait du 3ème argument de la fonction diff et somme je ne vois pas comment et pourquoi l'exploiter avec les éléments que j'ai...
    Car faire :
    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
    int somme(int a, int b) {
    	int c = a+b;
    	return c;
    }
    int diff(int a, int b) {
    	int d = a - b;
    	return d;
    }
     
    void calcul(int a, int b, int* c, int* d) {
    	*c = somme(a,b);
    	*d = diff(a,b);
     
    }
    int main() {
    	int a=0,b=0,c,d;
    	printf("Entrez la valeur de a et b\n");
    	scanf("%d%d",&a,&b);
     
    	calcul(a,b,&c,&d);
    	printf("la somme de a+b = %d, la difference entre a et b est de : %d", c,d);
    }
    Marche super bien dans ce cas posé, cependant ce qui vient ME poser problème est bien le fait que la fonction somme ne retourne rien (type void sans return) ainsi qu'un 3eme argument sans utilité pour moi (je dis bien pour moi n'ayant pas toutes les cartes pour comprendre cela...) pareil pour la fonction diff qui possède 3 arguments... Pourquoi ? je ne sais pas...

  11. #11
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    février 2006
    Messages
    7 596
    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 : 7 596
    Points : 21 642
    Points
    21 642
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Skz69 Voir le message
    Dans tous les cas, je reviens sur ce que tu dis Sve@r, je pense qu'on s'est mal compris, car le truc intéressent dans le poste de Guesset c'est sans doute l'utilisation de pointeur, sauf que c'est plus ou moins ce qui est fait dans mon code initial :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int calc(int a,int b,int* E,int* R) {
     
    	*E=somme(a,b,E);
    	*R=diff(a,b,R);
    }
    Plus ou moins. Sauf que lui il récupère un calcul correct alors que toi tu récupères un calcul "accidentel".
    Citation Envoyé par Skz69 Voir le message
    Concernant ta question en rapport avec scanf, voici la réponse :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void init(int* s) {
        *s=123;
    }
     
    int main() {
        int s=500;
        init(&s);
        printf("s=%d\n", s);
    }
    Je pense avoir plus ou moins compris ce concept d'adresse et de valeur &X représentant l'adresse de X et *X représentant la valeur associé à l'adresse de X si je ne m'abuse ?...
    Excellent. Tu as tout à fait compris.

    Maintenant imagine
    1. au lieu de mettre 123 tu y mets 120 + 3
    2. au lieu de mettre 120 + 3 tu y mets a + b ("a" et "b" étant aussi des paramètres reçus en plus de "s")

    La fonction "init()" ainsi modifiée ne correspond-elle pas à la fonction "somme()" telle que demandée ???

    Citation Envoyé par Skz69 Voir le message
    Cependant mon soucis étant également basé sur les fonctions, le passage de pointeur entre fonction etc... (en ayant eu un cours de 4h mardi, mélangeant tableau fonction et pointeur je suppose qu'il est logique que je m'embrouille un peu...)
    Oui (encore que mélanger "tableau" et "fonction" semble étonnant). Mais plus tard tu verras qu'un tableau peut être vu comme un pointeur (et inversement)

    Citation Envoyé par Skz69 Voir le message
    Dans tous les cas je vais étudier tout cela, cependant pouvez vous m'aiguiller, dois-je ici dans ce cas utiliser des pointeurs de pointeurs ? pour le passage fonction 1>2 puis 2>3 ? ou des simples pointeurs suffissent dans ce cas ?
    A mon avis, un exercice fait pour apprendre le pointeur ne t'embarquerait pas dans un pointeur de pointeur...

    Citation Envoyé par Skz69 Voir le message
    Les débats faisant rage, je vois qu'il n'est pas aisé de se mettre d'accord sur ce langage...
    Sisi, mis à part certains perturbateurs occasionnels qui viennent mettre un grain de sel absurde (et en plus ne correspondant pas à la demande), tous les habitués qui gravitent dans ce forum sont d'accord sur la marche à suivre...

    Citation Envoyé par Skz69 Voir le message
    du fait du 3ème argument de la fonction diff et somme je ne vois pas comment et pourquoi l'exploiter avec les éléments que j'ai...
    Etape par étape. Fais d'abord "somme()" et "diff()", teste les individuellement depuis le main().
    Et quand tu seras à l'aise rajoute ensuite "calcul()"

    Citation Envoyé par Skz69 Voir le message
    Dans tous les cas pour revenir sur le sujet initial, c'est que je ne comprends pas l'utilité de cet exercice
    Ca t'apprend à passer un pointeur à travers plusieurs fonctions successives. Des fois il y aura "&", des fois pas, des fois il y aura "*" et des fois pas. Le but étant que tu ne te trompes pas dans les différents appels et passages en sachant à chaque fois identifier ce que tu manipules.

    Citation Envoyé par Skz69 Voir le message
    Car faire :
    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
    int somme(int a, int b) {
    	int c = a+b;
    	return c;
    }
    int diff(int a, int b) {
    	int d = a - b;
    	return d;
    }
     
    void calcul(int a, int b, int* c, int* d) {
    	*c = somme(a,b);
    	*d = diff(a,b);
     
    }
    int main() {
    	int a=0,b=0,c,d;
    	printf("Entrez la valeur de a et b\n");
    	scanf("%d%d",&a,&b);
     
    	calcul(a,b,&c,&d);
    	printf("la somme de a+b = %d, la difference entre a et b est de : %d", c,d);
    }
    Marche super bien dans ce cas posé,
    Exact mais ne correspond pas à la demande. Soyons lucide: cet exercice ne sera jamais utilisé dans un truc opérationnel. On s'en fout en réalité des calculs qu'il fait. Son rôle est juste de t'apprendre à manipuler les pointeurs...
    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

  12. #12
    Membre confirmé

    Homme Profil pro
    Directeur de projet
    Inscrit en
    mai 2013
    Messages
    92
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : mai 2013
    Messages : 92
    Points : 540
    Points
    540
    Par défaut Fonds et forme
    Bonsoir,

    Citation Envoyé par Skz69 Voir le message
    ce qui vient ME poser problème est bien le fait que la fonction somme ne retourne rien (type void sans return) ainsi qu'un 3eme argument sans utilité pour moi (je dis bien pour moi n'ayant pas toutes les cartes pour comprendre cela...) pareil pour la fonction diff qui possède 3 arguments... Pourquoi ? je ne sais pas...
    C'était l'objet de l'échange sur le fond et la forme. En C toute routine est appelée fonction : c'est formel. Mais il y a de nombreux cas où il n'est pas utile d'avoir un retour. Auquel cas on l'indique avec un void. C l'appelle toujours formellement fonction mais sur le fond c'est une procédure car elle a un type non affectable c'est à dire qu'écrire void u = fn(a,b); n'a pas de sens. Elle peut cependant modifier le contenu de variables passées par adresse. Ce n'est plus un retour de fonction mais un retour direct de résultats.

    Le code est bon mais ils veulent que les résultats de somme et diff ne passent pas par deux fonction renvoyant un int mais par un troisième argument qui, a l'instar de calcul, sera un pointeur. Bien sûr il faudra modifier un peu calcul(...) pour s'y adapter.

    Bon courage.
    Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)

  13. #13
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    octobre 2019
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : octobre 2019
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    Bon après un petit passage sur les fonctions en questions je pense avoir trouvé une des solutions (car je suppose que ce n'est pas la seule...) cependant, mon compilateur ne m'insulte plus et la solution me semble viable

    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
     
    #include <stdio.h>
     
     
    void somme(int a, int b, int* c) {
    	*c = a+b;
    }
     
    int diff(int a, int b, int c) {
    	c = a-b;	
    	return c;
    }
     
    void calcul(int a, int b, int *c, int *d) {
    	int z,e;
    	somme(a,b,&z);
    	*d = diff(a,b,e);
    	*c = z;
    }
     
    int main() {
    	int a,b,c = 0,d = 0;
    	printf("Entrez la valeur de a et de b\n");
    	scanf("%d%d",&a,&b);
    	calcul(a,b,&c,&d);
    	printf("a+b=%d\na-b=%d\n",c,d);
    }
    Résultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    ***@deb:~***$ clang somme.c -o somme.e
    ***@deb:~***$ ./somme.e 
    Entrez la valeur de a et de b
    10
    5
    a + b =15
    a - b = 5
    ***@deb:~/***$
    J'ai cependant l'impression qu'une solution plus élégante existe... à voir avec vos commentaires.
    Merci dans tous les cas pour vos conseils.

  14. #14
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    février 2006
    Messages
    7 596
    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 : 7 596
    Points : 21 642
    Points
    21 642
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Skz69 Voir le message
    Bon après un petit passage sur les fonctions en questions je pense avoir trouvé une des solutions (car je suppose que ce n'est pas la seule...) cependant, mon compilateur ne m'insulte plus et la solution me semble viable
    Sisi, c'est la seule. On peut juste éviter certains intermédiaires inutiles

    Citation Envoyé par Skz69 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    int diff(int a, int b, int c) {
    	c = a-b;	
    	return c;
    }
     
    void calcul(int a, int b, int *c, int *d) {
    	int z,e;
    	somme(a,b,&z);
    	*d = diff(a,b,e);
    	*c = z;
    }
    Me semblait que "diff()" était comme "somme()" ie avec un pointeur. Parce que dans l'état, "c" ne sert à rien du tout.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    int diff(int a, int b, int c) {
    	return a-b;
    }
     
    void calcul(int a, int b, int *c, int *d) {
    	somme(a, b, c);
    	*d=diff(a, b, 0);
    }
    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

  15. #15
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    octobre 2019
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : octobre 2019
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    Oui je me rend bien compte que C ne sert a rien et pourtant il s'agit bien de l'énoncé (dans mon premier post j'ai commis une erreur)
    La fonction diff a bien trois paramètre (a et b puis une variable pour stocker le résultat) et un retour (écris en gras dans mon énoncé je suppose donc qu'il s'agit vraiment d'un return et pas d'un pointeur) sauf qu'en l'état, son troisième paramètre est inutile....
    Sinon si diff avait été comme somme, la démarche aurait été la même.

    Quant à ta solution merci je ne pensais pas pouvoir faire cela lors de l'appel de la fonction somme tout bêtement.
    Dans tous les cas je commence a me faire a cette notion, mais elle ne sera parfaitement maîtrisé que dans quelques temps... C'est assez déroutant ça me rappelle pas mal mes vieux cours d'assembleur en DUT...

    C'est en tout cas un langage bien différent des langages de haut niveau que j'utilise en admin sys/réseau...

  16. #16
    Expert éminent
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    juillet 2013
    Messages
    3 058
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : juillet 2013
    Messages : 3 058
    Points : 6 754
    Points
    6 754
    Par défaut
    Citation Envoyé par Skz69 Voir le message
    J'ai cependant l'impression qu'une solution plus élégante existe... à voir avec vos commentaires.
    Oui des solutions élégantes existent ... mais il ne faut pas coder comme un étudiant

    Voici un bout de code un peu surfait parce que l'exercice est ultra-minimaliste, mais tu as un bon aperçu de comment programmer en C niveau 0 (*) : structure avec interface, typedef, pointeurs de fonction, type variable ... mais peut-être un peu trop de #define

    Code 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
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    #include <stdio.h>
    #include <stdlib.h>
    
    
    /***************************** Structure & Define ****************************/
    
    #define RESULT_TYPE int // maybe a float/ double
    
    
    typedef struct s_two_values {
        int a;
        int b;
    
        RESULT_TYPE result;
    } t_two_values;
    
    
    /********************************* Inferface *********************************/
    
    #define two_values_get_a(input) ((t_two_values*) input)->a
    #define two_values_get_b(input) ((t_two_values*) input)->b
    
    /*#define two_values_get_result(input) ((t_two_values*) input)->result
    or*/
    RESULT_TYPE two_values_get_result(t_two_values* input) {
        RESULT_TYPE ret = 0;
    
        if (input != NULL) {
            ret = input->result;
        } else {
            ret = 0;
        }
    
        return ret;
    }
    
    
    void two_values_reset(t_two_values* input) {
        if (input != NULL) {
            input->a      = 0;
            input->b      = 0;
            input->result = 0;
        }
    }
    
    
    void two_values_scanf_a(t_two_values* input) {
        if (input != NULL) {
            scanf("%d", &(input->a));
        }
    }
    
    
    void two_values_scanf_b(t_two_values* input) {
        if (input != NULL) {
            scanf("%d", &(input->b));
        }
    }
    
    
    void two_values_set_result(t_two_values* input, RESULT_TYPE result) {
        if (input != NULL) {
            input->result = result;
        }
    }
    
    
    /********************************* Operations ********************************/
    
    typedef RESULT_TYPE (*t_op_func) (t_two_values*);
    
    
    #define op_exec(func, value) func(value)
    /* or
    RESULT_TYPE op_exec(t_op_func func, t_two_values* value) {
        return func(value);
    }*/
    
    
    RESULT_TYPE func_sum(t_two_values* input) {
        RESULT_TYPE ret = 0;
    
        if (input != NULL) {
            ret = (two_values_get_a(input) + two_values_get_b(input));
            two_values_set_result(input, ret);
        } else {
            ret = 0;
        }
    
        return ret;
    }
    
    
    RESULT_TYPE func_diff(t_two_values* input) {
        RESULT_TYPE ret = 0;
    
        if (input != NULL) {
            ret = (two_values_get_a(input) - two_values_get_b(input));
            two_values_set_result(input, ret);
        } else {
            ret = 0;
        }
    
        return ret;
    }
    
    
    /************************************ main ***********************************/
    
    int main (int argc, char** argv)
    {
        t_two_values two_values;
        RESULT_TYPE test_result;
    
        two_values_reset(&two_values);
    
        printf("Entrez la valeur de a\n");
        two_values_scanf_a(&two_values);
    
        printf("Entrez la valeur de b\n");
        two_values_scanf_b(&two_values);
    
        test_result = op_exec(func_sum, &two_values);
        printf("a + b = %d (test: %d)\n", two_values_get_result(&two_values), test_result);
    
        test_result = op_exec(func_diff, &two_values);
        printf("a - b = %d (test: %d)\n", two_values_get_result(&two_values), test_result);
    
    
        return EXIT_SUCCESS;
    }

    *: essentiellement pas d'allocations et pas de gestions d'erreurs

  17. #17
    Responsable Systèmes


    Homme Profil pro
    Technicien maintenance
    Inscrit en
    août 2011
    Messages
    11 715
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : août 2011
    Messages : 11 715
    Points : 26 191
    Points
    26 191
    Par défaut
    Quand tu passes des arguments en C à une fonction, ceux-ci sont recopiés dans des variables locales à la fonction. Ca s'appelle un passage de paramètres par valeur. L'inverse étant le passage par référence. Dans un passage par référence, pas de variables locales utilisées, se sont les arguments qui sont directement utilisables. Le C ne permet que le passage de paramètres par valeurs. Utilisez des pointeurs va permettre de simuler un passage de paramètres par référence.

    Pour retourner une valeur hors de la fonction, il faut utiliser le mot clé return avec une des variables locales à la fonction, du type de retour attendu par la fonction, car à la sortie de la fonction, ses variables locales sont détruites.

    Rappel : un pointeur est une variable typée qui contient l'adresse d"une variable de son type qui va elle contenir une valeur.

    Passer un pointeur en argument à une fonction permet de pouvoir utiliser la même donnée avec 2 variables différentes pointant sur la même adresse donc le même contenu, et donc de contourner le fait de voir faire un return.

    Exemple : certaines fonctions C de traitement sur les chaines de caractères modifient la chaine passée en paramètre mais retournent un int ayant une signification (comme erreur/ok)
    Ma page sur developpez.com : http://chrtophe.developpez.com/ (avec mes articles)
    Mon article sur la création d'un système : http://chrtophe.developpez.com/tutoriels/minisysteme/
    Mon article sur le P2V : http://chrtophe.developpez.com/tutoriels/p2v/
    Consultez nos FAQ : Windows, Linux, Virtualisation

  18. #18
    Expert éminent
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    juillet 2013
    Messages
    3 058
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : juillet 2013
    Messages : 3 058
    Points : 6 754
    Points
    6 754
    Par défaut
    Citation Envoyé par chrtophe Voir le message
    Pour retourner une valeur hors de la fonction, il faut utiliser le mot clé return avec une des variables locales à la fonction, du type de retour attendu par la fonction, car à la sortie de la fonction, ses variables locales sont détruites.
    Justement, j'ai dû mal avec ta phrase

    Il ne faut pas retourner l'adresse d'1 variable locale. Mais on peut faire une allocation à l'intérieur de la fonction et retourner l'adresse de cette zone (la variable locale sera détruite mais pas la zone allouée vers laquelle elle pointe) (<- *)
    C'est justement 1 des problèmes du C (peut-être du C++) : il faut savoir si une fonction fait une allocation ou pas (afin d'éviter les fuites mémoire)

    *: Éditée suite à la remarque de @Sve@r


    Citation Envoyé par chrtophe Voir le message
    Passer un pointeur en argument à une fonction permet de pouvoir utiliser la même donnée avec 2 variables différentes pointant sur la même adresse donc le même contenu, et donc de contourner le fait de voir faire un return.
    Un cas particulier : la création d'un pointeur

    Soit tu passes un double pointeur (**, deux étoiles l'adresse d'un pointeur) afin de pouvoir le modifier en lui attribuant une zone mémoire allouée dans la fonction (1), soit tu retournes le pointeur de cette zone (1) (et d'assigner le retour dans le pointeur que tu veux modifier ce qui évite de passer son adresse à cette fonction comme paramètre)


    Citation Envoyé par chrtophe Voir le message
    certaines fonctions C de traitement sur les chaines de caractères modifient la chaine passée en paramètre mais retournent un int ayant une signification (comme erreur/ok)
    Effectivement je voulais en parler : tu retournes un booléen qui n'existe pas en C (0 c'est faux, un autre entier est vrai) et ainsi pouvoir tester le retour.
    Mais, il faut en général un paramètre additionnel (de type pointeur) pour stocker un code erreur (<- ceci permet de limiter les codes erreurs à un type énuméré, parce que si tu retournes directement un code erreur tu peux avoir tout et n'importe quoi)

  19. #19
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    février 2006
    Messages
    7 596
    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 : 7 596
    Points : 21 642
    Points
    21 642
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Skz69 Voir le message
    Oui je me rend bien compte que C ne sert a rien et pourtant il s'agit bien de l'énoncé (dans mon premier post j'ai commis une erreur)
    Ok, pas de mal

    Citation Envoyé par Skz69 Voir le message
    La fonction diff a bien trois paramètre (a et b puis une variable pour stocker le résultat) et un retour (écris en gras dans mon énoncé je suppose donc qu'il s'agit vraiment d'un return et pas d'un pointeur) sauf qu'en l'état, son troisième paramètre est inutile....
    Probablement une erreur de l'énoncé.

    Citation Envoyé par Skz69 Voir le message
    Sinon si diff avait été comme somme, la démarche aurait été la même.
    Evidemment. Comme je te l'avais dit au départ, les calculs eux-mêmes n'ont pas vraiment d'importance...

    Citation Envoyé par Skz69 Voir le message
    Quant à ta solution merci je ne pensais pas pouvoir faire cela lors de l'appel de la fonction somme tout bêtement.
    Tu avais écrit int z; somme(a,b,&z); *c = z;. Il faut bien sentir les implications de l'égalité. Une égalité ça va dans tous les sens. Si *c égale z alors z égale *c alors &z égale &*c et comme les opérateur "&" et "*" s'annulent, &z égale c.
    Ou plus prosaiquement, c contient une adresse où stocker le résultat, somme() veut une adresse où stocker le résultat => on lui passe "c" tout bêtement. Comme je l'ai dit, ça t'apprend à manipuler un pointeur, le transférer ailleurs, etc...

    Citation Envoyé par Skz69 Voir le message
    C'est en tout cas un langage bien différent des langages de haut niveau que j'utilise en admin sys/réseau...
    Si t'es habitué au haut niveau alors ça va te piquer les yeux. Quand tu mettras 30 lignes pour calculer un masque ou faire un truc qui prend 1 ligne dans d'autres langages...

    Citation Envoyé par chrtophe Voir le message
    Utilisez des pointeurs va permettre de simuler un passage de paramètres par référence.
    Rhaaa que j'aime pas cette phrase. On a l'impression que le C cherche à faire un truc déjà fait ailleurs (le passage par références du C++)

    Or rappelons tout de même que le C était le premier. C'est lui qui a défini le fait qu'une valeur était toujours recopiée dans une fonction et qui a alors créé le pointeur pour pouvoir modifier une varaible qui lui est extérieure.
    Le C++ est arrivé après et a alors créé le concept de passage par références probablement juste pour ne plus avoir à utiliser de pointeurs.

    Citation Envoyé par chrtophe Voir le message
    Pour retourner une valeur hors de la fonction, il faut utiliser le mot clé return avec une des variables locales à la fonction,
    Ah bon ? Parce que le return avec une valeur en dur est impossible ?

    Citation Envoyé par chrtophe Voir le message
    Rappel : un pointeur est une variable typée qui contient l'adresse d"une variable de son type qui va elle contenir une valeur.
    C'est vrai évidemment mais bon, un pointeur contient lui aussi à la base une valeur quoi...

    Citation Envoyé par chrtophe Voir le message
    Passer un pointeur en argument à une fonction permet de pouvoir utiliser la même donnée avec 2 variables différentes pointant sur la même adresse donc le même contenu, et donc de contourner le fait de voir faire un return.
    Tes explications manquent de simplicité et de clarté. Un pointeur permet simplement à une fonction d'accéder à une zone mémoire située hors de son espace de noms.

    Citation Envoyé par foetus Voir le message
    Il ne faut pas retourner une variable locale
    Ben si, t'as le droit !!!!
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int carre(int n) {
        int r=n*n;
        return r;
    }
    Je ne vois pas ce qui pose problème même avec "r" détruit en fin de fonction. Sa valeur, elle, est quand-même récupérée.

    Ce que tu n'as pas le droit de faire c'est retourner l'adresse d'une variable locale !!! Car la variable étant détruite, tu retournes une adresse ne correspondant plus à quelque chose de valide.
    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

  20. #20
    Responsable Systèmes


    Homme Profil pro
    Technicien maintenance
    Inscrit en
    août 2011
    Messages
    11 715
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : août 2011
    Messages : 11 715
    Points : 26 191
    Points
    26 191
    Par défaut
    tu retournes un booléen qui n'existe pas en C
    Oui je me suis mal exprimé. Je ne parlais pas de booléen mais d'une valeur signifiant ok ou qu'il y a une erreur. Une fonction va retourner 0 en cas de succès ou la longueur de la chaine pour la fonction strlen() par exemple. Une valeur négative signifiera qu'il y a eu une erreur, une interrogation de errno donnant l'explication de l'erreur. Le man de la fonction donnera les valeurs de retour.
    Ma page sur developpez.com : http://chrtophe.developpez.com/ (avec mes articles)
    Mon article sur la création d'un système : http://chrtophe.developpez.com/tutoriels/minisysteme/
    Mon article sur le P2V : http://chrtophe.developpez.com/tutoriels/p2v/
    Consultez nos FAQ : Windows, Linux, Virtualisation

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Impossible de retourner la valeur d'une fonction personnalisée sur Excel
    Par abdelben93 dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 10/05/2019, 09h10
  2. comment retourner 2 valeurs avec une fonction
    Par aminebakr dans le forum Langage
    Réponses: 14
    Dernier message: 27/06/2017, 12h58
  3. [XL-2007] Retourner la valeur d'une fonction sur une colonne
    Par renaudjean dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 04/10/2013, 02h27
  4. Pour retourner deux valeurs dans une fonction
    Par IMANE21 dans le forum Débuter
    Réponses: 1
    Dernier message: 04/03/2012, 00h36
  5. Retourner plusieurs valeurs a une fonction ajax
    Par Hyuge dans le forum jQuery
    Réponses: 2
    Dernier message: 11/06/2009, 16h49

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