bonjour ,
j'ai un souci ! je débute et j'aimerais avoir la définition précise du passage par adresse et en paramétre ( le prof en a parler sans expliquer)
merci:
bonjour ,
j'ai un souci ! je débute et j'aimerais avoir la définition précise du passage par adresse et en paramétre ( le prof en a parler sans expliquer)
merci:
Le vocabulaire exact est passage de paramètre par adresse ou par valeur. Cela tiens au fonctionnement de la mémoire d'un ordinateur : il y a des adresses mémoires, chacune pouvant avoir un contenu mémoire. Ainsi, pour un paramètre entier A, on peut passer à une fonction f aussi bien l'adresse mémoire de A que le contenu de A (un entier donc. Disons 15 par exemple). Dans le premier cas, le paramètre A peut être modifié depuis l'intérieur de la fonction, alors que c'est impossible dans le second cas. Dans les deux cas, il est bien sûr possible d'accéder au contenu (15 dans notre exemple).
Je pense qu'il faut bien s'accorder sur le sens de cette affirmation : tu veux dire par là que le bout de code suivant :
affichera "5 10" dans le cas d'un langage à appel par valeur alors qu'il affichera "10 10" dans le cas d'un langage à appel par référence.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 Fonction Modifie(entier A) : A <- 10 Renvoie A FinFonction entier N; N <- 5 M <- Modifie(N) Affiche(N) Affiche(M)
Une autre différence notable entre les deux modes d'appel est que dans le cas de l'appel par valeur, la valeur est copié entièrement sur la pile alors qu'avec l'appel par référence seule son adresse est copié sur la pile. Pour une valeur composée de grande taille comme un tableau, un gros objet ou structure, cela peut avoir de lourde conséquences sur les performances.
--
Jedaï
Ces propos, bien que je sois certains que leur auteur, maitrise bien le concept, peuvent porter à confusion. il est possible de modifier un paramètre depuis l'intérieur de la fonction, même dans un passage par valeur. Cependant lors du passage par valeur, les variables à l'intérieur et à l'extérieur de la fonction sont dissocié (par le biais de la copie), aussi toute modification à l'intérieur de la fonction n'aura aucune répercussion en dehors de la fonction. En gros, la variable que l'on passe en paramètre par valeur ne change pas.Dans le premier cas, le paramètre A peut être modifié depuis l'intérieur de la fonction, alors que c'est impossible dans le second cas.
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 void main() { <div style="margin-left:40px"> int a = 5; passageparvaleur(a); afficher(a); // 5 passageparreference(a); afficher(a); // 10</div>} void passageparvaleur(int a) { <div style="margin-left:40px">a=a*2; //modification (possible) du parametre a, n'ayant aucune incidence sur la variable a de la fonction main</div>} void passageparreference(int &a) { <div style="margin-left:40px">a=a*2;//modification du parametre a, impliquant une modification de la variable a de la fonction main</div>}Je me permet de mettre en doute cette affirmation. Mes informations datent un peu, il se peut donc que je me trompe, mais que ce soit un appel par valeur ou par référence,je pense que seule l'adresse mémoire est copié sur la pile.que dans le cas de l'appel par valeur, la valeur est copié entièrement sur la pile
La seule différence est que dans le cas d'un passage par valeur, une copie de l'objet est faite dans l'espace mémoire de l'application et que c'est l'adresse de cette copie qui est empilé alors que dans le cas d'un passage par réference, y'a pas de copie, c'est simplement l'adresse de l'objet qu'on emile.
Cela ne change en rien tout ce qui a été dit d'autre.
J'aimerais avoir la confirmation d'un spécialiste si possible.
Cela dépend peut-être du langage, mais dans le cas de C++ (ou C) par exemple je me permets de douter de ta version : cela impliquerait que lors du retour de la fonction, C++ soit conscient de quelles parties de la pile sont des pointeurs et aille libérer l'espace vers lequel ils pointent... Or l'avantage de la pile c'est justement qu'il n'y a rien à faire pour libérer l'espace à la fin d'une fonction, il suffit de changer la valeur du registre de pile. En bref ton interprétation exigerait une forme de GC intégré dans C++, ce qui me paraît improbable.
--
Jedaï
Non, pas en C/C++ en tout cas. L'objet est intégralement copié sur la pile, avec (de mémoire) un appel du constructeur par copie pour le C++ (en C, c'est un memcpy correspondant au sizeof qui est fait). Si ton objet fait 500 Mo, alors tu auras 500 Mo poussés sur la pile directement (=> stack overflow direct).
Seul un passage par référence garantit que seule l'adresse de l'objet (copie ou pas, peu importe) sera poussé sur la pile. Autrement, tu as au minimum sizeof(objet) octets poussés sur la pile.
Tu peux faire le test assez facilement à l'exécution, en affichant l'adresse de chaque paramètre de ta fonction, ainsi que le sizeof correspondant. Aux contraintes d'alignement près, tu verras que ça se suit parfaitement.
C'est pareil pour tous les langages impératifs natifs que j'ai manipulé consciencieusement, en tout cas, inclus Delphi/Pascal, Ada, C et C++. C'est peut-être différent pour les langages interprétés (ex : Python, LUA, ...) ou semi-interprétés (Java, .NET), mais là on arrive dans le monde des GC et autres gestions automatiques de la mémoire.
Partager