Passage de paramètre en C

Discutez d'informatique ici !
Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 18:42

Passage de paramètre en C

par Rockleader » 19 Juin 2014, 22:13

Avant toute chose, je vais dire ceci; non je ne teste pas vu que le but c'est d'arriver à tout expliquer sur une feuille ;)

Donc je cherche plutot à voir si ma démarche est correcte

Code: Tout sélectionner
int sournois(int n, int * m)
{
*m=*m+n;
return *m;
}

int main()
{

int a=5;
if(sournois(a,&a)==(sournois(a,&a))
{
   printf("1\n");
}
else
{
   printf("0\n");
}
return  0:
}




A la question qu'affiche le programme je répond 0

Car lors du premier appel de sournois(5,&5) on retourne 10 et a prend la valeur 10.
Second appel sournois(10,&10) retourne 20 et a prend la valeur 20.

10 != 20 ==> affichage de 0 et en fin de programme a=20.

Est ce bon ? (surtout pour l'explication).


Code: Tout sélectionner
void incr(int ** x)
{
**x=**x+1;
}


int main()
{
int a,b;
int *pab;
int **pp;
a=5; b=6;
pab=&a;
pp=&pab;
incr(pp);
pab=&b;
incr(pp);

return 0
}


On cherche les valeurs de a et b à la fin.

==> pab=&a=&5;
pp=&pab=&&5;
incr(&&5) ==> a prend la valeur 6.
pab=&b=&6;
incr(pp=&pab=&&b=&&6) ==> b prend la valeur 7

Donc à la fin a=6 et b=7 ?






Mes résultats / explications sont ils correct ou bien j'ai encore des lacunes sur les pointeurs ? :hum:



Merci à vous ;)
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !



Avatar de l’utilisateur
fatal_error
Membre Légendaire
Messages: 6610
Enregistré le: 22 Nov 2007, 12:00

par fatal_error » 19 Juin 2014, 23:36

Avant toute chose, je vais dire ceci; non je ne teste pas vu que le but c'est d'arriver à tout expliquer sur une feuille ;)

Donc je cherche plutot à voir si ma démarche est correcte

ben déjà tu peux au moins vérifier que ton raisonnement est pas faux en regardant que tu as bien le même résultat que celui prédit. :mur:

&5 ca veut rien dire. c'est faux de base.


==> pab=&a=&5;
pp=&pab=&&5;
si tu dis pab=27, pp=&pab c'est pas l'adresse de 27... c'est juste l'adresse de ta variable pab...
tout ce que tu peux dire c'est *pp==pab==27

ps:
Donc je cherche plutot à voir si ma démarche est correcte

ben t'as qu'à checker étape par étape en affichant la valeur des variables de chaque ligne du programme...
de toute facon ca vaut mieux qu avaler cqu on dit, au moins t auras fait une manipulation.

ps2:
ca devient marrant si tu mets des const keywords :)
la vie est une fête :)

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 18:42

par Rockleader » 20 Juin 2014, 00:24

Quand j'écris &5 je sais que ça ne veut rien dire^^

J'entends par là adresse de la variable contenant 5. J'écris seulement &5 pour avoir la valeur sous les yeux, je te l'accorde c'est plutôt maladroit, mais autrement je ne vois pas comment l'expliquer...bref du coup tu m'as forcé à faire le test, je l'ai fait pour le premier et il semble que j'avais les bons résultats théoriques, ce qui me rassure quand même^^

Mais quand on te demande d'expliquer comment on trouve le résultat faut bien passer par du blabla...
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

Avatar de l’utilisateur
ampholyte
Membre Transcendant
Messages: 3940
Enregistré le: 21 Juil 2012, 07:03

par ampholyte » 20 Juin 2014, 07:51

Bonjour,

Pour le blabla, il faut plutôt parler "on pointe sur l'adresse de a", "on prend l'adresse de a", ...

Pour t'aider utilise uniquement le nom des variables.

A partir du moment où :
a = 5 alors n'importe quelle pointeur pointant sur l'adresse de a aura pour valeur 5.
C'est un peu la définition du pointeur.

Si on incrémente a, alors a = 6 et tous les pointeurs pointant sur l'adresse a auront pour valeur 6.

Comme l'explique fatal-error, si tu parles de &5, ton prof pourra croire que tu n'as rien compris (même en ayant un résultat juste).

Par contre si tu expliques, que la valeur du pointeur pointant sur a vaut 5 car a vaut 5, c'est déjà plus clair ^^.

Avatar de l’utilisateur
ampholyte
Membre Transcendant
Messages: 3940
Enregistré le: 21 Juil 2012, 07:03

par ampholyte » 20 Juin 2014, 08:13

Bonjour,

Lors que tu essayes d'expliquer le fonctionnement d'un programme avec des pointeurs, il est nécessaire d'utiliser certains mots clef (adresse, pointe, pointeur, mémoire, variable, ...).

Prenons la ligne :
Code: Tout sélectionner
pab=&a;


Le pointeur pab pointe sur la variable a. pab a pour valeur l'adresse de a.

Code: Tout sélectionner
*pab += 1

Ici on incrémente la valeur se trouvant à l'emplacement mémoire sur lequel pointe pab (c'est à dire a).

Est-ce que tu comprends le principe des explications.

Bien sûr tu peux raccourcir, mais vu que tu as dû mal à expliquer le code, c'est que tu ne maitrise pas encore très bien la théorie des pointeurs (et c'est normal, c'est une des notions complexes du C).

Rien de nouveau, il faut simplement pratiquer pratiquer et pratiquer.

Un petit exemple qui peut poser problème quand on démarre sur les pointeurs, c'est souvent au niveau de l'initialisation.

Code: Tout sélectionner
typedef struct {
   int value1;
   int value2;
} Toto;

Toto *init_toto_1() {
    Toto *res = NULL;
    res = calloc(1, sizeof(*res));
    if (res == NULL) {
        fprintf(stderr, "Error allocation memory\n");
    }
   
     res->value1 = 5;
     res->value2 = 6;

    return (res);
}

int init_toto_2(Toto *out) {
    out = calloc(1, sizeof(*out));
    if (out == NULL) {
         fprintf(stderr, "Error allocation memory\n");
         return (-1);
    }

     out->value1 = 5;
     out->value2 = 6;

    return (1);
}

int init_toto_3(Toto **out) {
   *out = calloc(1, sizeof(**out));
    if (*out == NULL) {
         fprintf(stderr, "Error allocation memory\n");
         return (-1);
    }

     (*out)->value1 = 5;
     (*out)->value2 = 6;

    return (1);
}

int main(void) {
    Toto *toto = NULL;
     toto = init_toto_1();
     if (toto != NULL) {
          fprintf(stdout, "init1 : %d %d\n", toto->value1, toto->value2);
          free(toto);
          toto = NULL;
     }


     init_toto_2(toto);
     if (toto != NULL) {
          fprintf(stdout, "init2 : %d %d\n", toto->value1, toto->value2);
           free(toto);
           toto = NULL;
     }

     init_toto_3(&toto);
     if (toto != NULL) {
          fprintf(stdout, "init3 : %d %d\n", toto->value1, toto->value2);
          free(toto);
          toto = NULL;
     }
     
     return (0);
}


Pourquoi dans la seconde fonction toto est NULL ?

Cliffe
Membre Rationnel
Messages: 967
Enregistré le: 12 Juin 2012, 13:25

par Cliffe » 20 Juin 2014, 10:26

Pcq tu lui passe un pointeur null en paramètre : (Toto * out = NULL)
Ensuite tu alloue ton objet et tu sort de la fonction avec un memory leak.

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 18:42

par Rockleader » 20 Juin 2014, 11:18

Merci ;)


Finalement dans mon exo de passage de paramètre il n'y avait pas de pointeurs; mais ça m'a un peu destabilisé du coup



yavait un void sournois(int y) qui fesait juste x=x*y

Et le X était en fait déclaré en global.

Du coup dans le main()

On avait ça

X=5
z=sournois(3);


En sortie Z vaut 15 ça parait plutôt logique, mais j'ai longtemps hésité si X gardait la valeur 5 ou bien s'il était modifié vu qu'il en global.

J'ai finalement opté pour X=15 et Z=15 sur un morceau de code comme celui là; j'avais un conflit dans mon esprit sur la portée des variables, non pas que je ne comprenne pas; masi que la situation était assez sournoise pour se poser des questions^^
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

Avatar de l’utilisateur
ampholyte
Membre Transcendant
Messages: 3940
Enregistré le: 21 Juil 2012, 07:03

par ampholyte » 20 Juin 2014, 13:09

Cliffe a écrit:Pcq tu lui passe un pointeur null en paramètre : (Toto * out = NULL)
Ensuite tu alloue ton objet et tu sort de la fonction avec un memory leak.


Je posais la question à Rockleader pour qu'il puisse y réfléchir :'( (je connais la réponse ^^)

 

Retourner vers ϟ Informatique

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 6 invités

Tu pars déja ?



Fais toi aider gratuitement sur Maths-forum !

Créé un compte en 1 minute et pose ta question dans le forum ;-)
Inscription gratuite

Identification

Pas encore inscrit ?

Ou identifiez-vous :

Inscription gratuite