Problème fonctions C++
Résolu
Bonjour,
J'ai une fois de plus besoin de vous! ^^
1)
int max1(int a , int b){
if(a>b) return a;
else return b;
}
int & max2(int & a , int & b){
if(a>b) return a;
else return b;
}
int & max3(int a , int b){
if(a>b) return a;
else return b;
}
Pourriez-vous m'expliquer ce que fait exactement la fonction max2 par rapport à la fonction max1?
J'ai cru comprendre qu'elle retournait une adresse mais :
2)
J'ai vu ensuite que:
max1(x,y) n'est pas une lvalue
max2(x,y) est une lvalue!
Mais pourquoi?? Je croyais que les adresses ne pouvaient pas être en partie gauche d'une affectation!
Et une dernière chose:
Pourquoi la fonction max3 est incorrecte?
Merci d'avance pour vos réponses!
J'ai une fois de plus besoin de vous! ^^
1)
int max1(int a , int b){
if(a>b) return a;
else return b;
}
int & max2(int & a , int & b){
if(a>b) return a;
else return b;
}
int & max3(int a , int b){
if(a>b) return a;
else return b;
}
Pourriez-vous m'expliquer ce que fait exactement la fonction max2 par rapport à la fonction max1?
J'ai cru comprendre qu'elle retournait une adresse mais :
2)
J'ai vu ensuite que:
max1(x,y) n'est pas une lvalue
max2(x,y) est une lvalue!
Mais pourquoi?? Je croyais que les adresses ne pouvaient pas être en partie gauche d'une affectation!
Et une dernière chose:
Pourquoi la fonction max3 est incorrecte?
Merci d'avance pour vos réponses!
A voir également:
- Problème fonctions C++
- Codes secrets Android : accéder aux fonctions cachées - Guide
- Fonctions excel en anglais - Guide
- Fonctions excel - Guide
- Impossible d'installer hyper-v le processeur ne dispose pas des fonctions de virtualisation requises - Forum Windows 8 / 8.1
- Fonction puissance c++ - Forum C++
3 réponses
Ce ne sont pas des adresses mais des références. Syntaxiquement parlant tout se passe comme si tu manipulait le type de l'objet (ici int), mais informatiquement parlant tout se passe comme si tu manipulais le pointeur. Ainsi :
En effet en C et en C++ une fonction duplique ses paramètre en mémoire (et c'est pour ca que les références et les pointeurs permettent de manipuler efficacement des grosses structures, car on ne recopie que l'adresse). En l'occurrence il ne faut jamais retourner une référence (ou une adresse) d'une variable locale à ta fonction, car cette valeur sera détruite dès que la fonction sera quitté.
De manière plus générale dès que tu sors d'un bloc { ... } que ce soit une boucle ou une fonction, tu quitte ce qu'on appelle un scope (horizon) et toutes les variables locales à ce scope sont détruites. C'est typiquement ce qui se passe dans max3 : a et b sont des recopies des variables a et b du main (donc des variables locales à la fonction), et tu retournes une référence sur a ou b, qui seront toutes deux désallouées à la fin de max3.
C'est pour ca qu'il faut soit que les variables devant "survivre" à un scope doivent soit provenir d'un scope plus global (comme dans max1), ou doivent être allouées dans la fonction via un new ou un malloc (le pointeur en tant que variable locale sera détruit, mais pas la variable à cette adresse).
En toute rigueur ta fonction max2 s'écrit ainsi (car elle ne modifie pas les entiers a et b) :
Note que tu peux aussi directement utiliser std::max après avoir inclu le header <cmath>
Bonne chance
#include <iostream> void incrementer1(int x){ ++x; } void incrementer2(int & x){ ++x; } void incrementer3(int *x){ ++*x; } int main(){ int x = 28; std::cout << x << std::endl; // 28 incrementer1(x); // x n'est modifié qu'à l'intérieur du scope de incrementer1 std::cout << x << std::endl; // 28 incrementer2(x); std::cout << x << std::endl; // 29 incrementer3(x); std::cout << x << std::endl; // 30 return 0; }
En effet en C et en C++ une fonction duplique ses paramètre en mémoire (et c'est pour ca que les références et les pointeurs permettent de manipuler efficacement des grosses structures, car on ne recopie que l'adresse). En l'occurrence il ne faut jamais retourner une référence (ou une adresse) d'une variable locale à ta fonction, car cette valeur sera détruite dès que la fonction sera quitté.
De manière plus générale dès que tu sors d'un bloc { ... } que ce soit une boucle ou une fonction, tu quitte ce qu'on appelle un scope (horizon) et toutes les variables locales à ce scope sont détruites. C'est typiquement ce qui se passe dans max3 : a et b sont des recopies des variables a et b du main (donc des variables locales à la fonction), et tu retournes une référence sur a ou b, qui seront toutes deux désallouées à la fin de max3.
C'est pour ca qu'il faut soit que les variables devant "survivre" à un scope doivent soit provenir d'un scope plus global (comme dans max1), ou doivent être allouées dans la fonction via un new ou un malloc (le pointeur en tant que variable locale sera détruit, mais pas la variable à cette adresse).
En toute rigueur ta fonction max2 s'écrit ainsi (car elle ne modifie pas les entiers a et b) :
const int & max2(const int & a,const int & b){ if (a<b) return b; return a; }
Note que tu peux aussi directement utiliser std::max après avoir inclu le header <cmath>
Bonne chance
Oh!! Un très très grand MERCI!!!
J'ai confondu adresse et référence!!
Encore merci!!
( Ayant un gros trou au niveau de la notion de référence j'ai regardé ce qu'un internaute avait expliqué sur un autre site, si cela intéresse quelqu'un voilà le lien:
https://forum.hardware.fr/hfr/Programmation/reference-sujet_8503_1.htm )
J'ai confondu adresse et référence!!
Encore merci!!
( Ayant un gros trou au niveau de la notion de référence j'ai regardé ce qu'un internaute avait expliqué sur un autre site, si cela intéresse quelqu'un voilà le lien:
https://forum.hardware.fr/hfr/Programmation/reference-sujet_8503_1.htm )
Très belle explication.
Une correction minuscule dans le main:
incrementer3(&x);
Comme le paramètre est explicitement un pointeur il faut passer explicitement une adresse.
M.