logo Debian Debian Debian-France Debian-Facile Debian-fr.org Forum-Debian.fr Debian ? Communautés logo inclusivité

Debian-facile

Bienvenue sur Debian-Facile, site d'aide pour les nouveaux utilisateurs de Debian.

Vous n'êtes pas identifié(e).

#1 29-12-2016 02:46:08

hukros
Membre
Lieu : Nouméa
Distrib. : Debian Jessie 8
Noyau : Linux 3.16.0-4-686-pae
(G)UI : KDE
Inscription : 28-10-2016

Explication programmation [Résolu]

Bonjour à tous,

J'aurai souhaité que l'on m'explique le passage par paramètre ou par valeur et dans quel cas vaut il mieux utiliser l'un que l'autre? Je demande cela car j'ai gros soucis en algorithme sur les liste chaînée. Et je pense que c'est la base pour comprendre et savoir utilisé les fameuses liste chaînée.

D'avance merci,

Hukros

Dernière modification par hukros (26-02-2017 00:46:06)

Hors ligne

#2 29-12-2016 11:50:12

enicar
Membre
Lieu : pas ici
Distrib. : sid
Noyau : Linux 6.5.3
(G)UI : openbox
Inscription : 26-08-2010

Re : Explication programmation [Résolu]

Bonjour,
Je ne sais pas ce que tu appelles « passage par paramètre », par contre je connais le
passage par référence (ou par adresse).
La façon de l'expliquer dépend du langage avec lequel tu travailles, bien que le
mécanisme soit strictement le même.
Dans les langages de bas niveau comme le C on peut explicitement utiliser
le passage par valeur ou par adresse. On se place dans le cadre d'un appel
de fonction. Par défaut les arguments sont passés par valeurs. Cela veut dire
que l'on passe uniquement des copies des valeurs passées en paramètre
à la fonction, la fonction  ne peut modifier que la valeur locale qu'il
lui est transmise.

Quand on passe les paramètres par adresse, cela veut dire que l'on passe l'adresse
de la variable (et non plus juste sa valeur). Donc la fonction obtenant cette adresse
peut modifier directement ce qui s'y trouve et donc modifier le contenu (la valeur)
de la variable qui est passée par adresse.

Si tu nous disais quel langage tu utilise, je pourrais te montrer un exemple de ce mécanisme

Hors ligne

#3 30-12-2016 21:10:57

hukros
Membre
Lieu : Nouméa
Distrib. : Debian Jessie 8
Noyau : Linux 3.16.0-4-686-pae
(G)UI : KDE
Inscription : 28-10-2016

Re : Explication programmation [Résolu]

Bonjour

Et merci enicar pour ta réponse, je pratique du C.Désolé j'aurai dû le préciser sur mon précédant poste.

Joyeuse fête à tous

Hors ligne

#4 31-12-2016 00:41:10

enicar
Membre
Lieu : pas ici
Distrib. : sid
Noyau : Linux 6.5.3
(G)UI : openbox
Inscription : 26-08-2010

Re : Explication programmation [Résolu]

Donc voici, un petit programme de démonstration très succinct :


/* programme de démonstration des arguments passés par valeur et par
 * addresse
 */


#include <stdio.h>

void par_addresse(int *entier) {
        *entier = *entier + 1;
}

void par_valeur(int entier) {
    entier = entier + 1;
}



int main(void) {
    int un_entier = 2;

    printf("valeur initiale de 'un_entier': %d\n", un_entier);
    par_valeur(un_entier);
    printf("valeur après appel de la fonction 'par_valeur': %d\n", un_entier);
    par_addresse(&un_entier);
    printf("valeur après appel de la fonction 'par_addresse': %d\n", un_entier);
return 0;
}
 



Produit la sortie suivante :


valeur initiale de 'un_entier': 2
valeur après appel de la fonction 'par_valeur': 2
valeur après appel de la fonction 'par_addresse': 3
 



Dans les deux fonctions par_addresse et par_valeur on
ajoute un à l'argument.

Dans la fonction par_valeur on passe une copie de la valeur de
un_entier. Au retour de la fonction sa valeur n'a pas changé.

Dans la fonction par_adresse on passe l'adresse de la variable
en argument grâce à &entier. Cette fonction attend bien
l'addresse d'une variable qui représente un entier, c'est ce que
dit la déclaration int *entier. Ce qui veut dire que
*entier est un int. Et donc que entier est un pointeur
vers un int. C'est pour cela que dans cette fonction pour additionner
un je travaille sur *entier (et non sur entier qui est une
addresse…).
Du coup je modifie bien ce qu'il y a a l'adresse « entier » qui
correspond à l'addresse de « un_entier » dans le main. Et j'ajoute
effectivement un à « un_entier ».

J'espère avoir été clair wink
Tu peux compiler ce petit exemple, et  l'exécuter pour voir le
résultat par toi même smile

Dernière modification par enicar (31-12-2016 00:52:30)

Hors ligne

#5 31-12-2016 12:49:13

enicar
Membre
Lieu : pas ici
Distrib. : sid
Noyau : Linux 6.5.3
(G)UI : openbox
Inscription : 26-08-2010

Re : Explication programmation [Résolu]

J'ai envie de compléter ma réponse. On peut obtenir l'adresse  d'une variable,
et on peut aussi l'afficher grâce au format %p dans printf, ce qui m'amène à proposer
cette petite expérience :


/* programme de démonstration des arguments passés par valeur et par
 * addresse : observation des adresses des variables.
 */


#include <stdio.h>

void par_adresse(int *entier) {
        printf("Dans 'par_adresse'\n");
        printf("valeur de '*entier' : %d\n", *entier);
        printf("valeur de 'entier' : %p\n", entier);
        printf("valeur de l'adresse de 'entier' : %p\n", &entier);
}

void par_valeur(int entier) {
    printf("Dans 'par_valeur'\n");
    printf("valeur de 'entier': %d\n", entier);
    printf("Valeur de l'addresse de 'entier' : %p\n", &entier);
}



int main(void) {
    int un_entier = 2;
   
    printf("Dans main\n");
    printf("valeur initiale de 'un_entier' dans main: %d\n", un_entier);
    printf("valeur de l'adresse de 'un_entier' : %p\n", &un_entier);
    par_valeur(un_entier);
    par_adresse(&un_entier);
}


 


Ce qui produit la sortie :


Dans main
valeur initiale de 'un_entier' dans main: 2
valeur de l'adresse de 'un_entier' : 0x7ffd5cc6078c
Dans 'par_valeur'
valeur de 'entier': 2
Valeur de l'addresse de 'entier' : 0x7ffd5cc6076c
Dans 'par_adresse'
valeur de '*entier' : 2
valeur de 'entier' : 0x7ffd5cc6078c
valeur de l'adresse de 'entier' : 0x7ffd5cc60768
 



Dans par_valeur, l'adresse de entier (&entier)
n'a rien à voir avec l'adresse de un_entier dans main.

Dans par_adresse la valeur de entier est égale
à l'adresse de un_entier dans main. La valeur rangée
à cette adresse est *entier et est égale à 2.
L'adresse &entier n'a rien à voir avec l'adresse de
un_entier, car ces deux variables occupent des places
différentes en mémoire.

Si tu compiles et exécutes ce programme, en général, tu n'obtiendra
pas les mêmes valeurs pour les adresses.

Voilà, c'est pas facile d'expliquer ces histoires, mais j'espère que
tu auras compris wink

Et bonne fête de fin d'années !

EDIT: un livre qu'il faut absolument lire lorsqu'on apprend le C :
Le langage C par les créateurs du langage : Brian W. Kernighan et Dennis M. Ritchie.

Dernière modification par enicar (31-12-2016 12:54:14)

Hors ligne

#6 03-01-2017 00:48:43

hukros
Membre
Lieu : Nouméa
Distrib. : Debian Jessie 8
Noyau : Linux 3.16.0-4-686-pae
(G)UI : KDE
Inscription : 28-10-2016

Re : Explication programmation [Résolu]

Bonjour,

Bonjour et merci pour l'explication.

Donc si je résume bien, le passage par valeur on agit directement sur deux variables totalement indépendante. Tandis que si l'on passe par adresse on modifie que la variable passer en paramètre dans le main.

Pour ce qu'y est du livre j'ai la 3ème édition mais j'ai beaucoup de mal avec les listes chaînées et je comprend pas même avec les explication dans le livre.

Désolé si je dit des grosse beptise mais j'ai des grosses difficulté en algorithmique et de ce faite j'essaye d'y remédier par d'autres moyen que les polycopier de l'université.

Hukros.

Dernière modification par hukros (03-01-2017 00:52:20)

Hors ligne

Pied de page des forums