Outils d'utilisateurs

Outils du Site


parametres_arguments

Différences

Cette page vous donne les différences entre la révision choisie et la version actuelle de la page.

Lien vers cette vue

parametres_arguments [2018/05/17 13:29]
gbdivers
parametres_arguments [2018/06/23 20:25] (Version actuelle)
winjerome Correction orthographique
Ligne 6: Ligne 6:
 ====== Les paramètres de fonctions ====== ====== Les paramètres de fonctions ======
  
-Lorsque vous appelez une fonction, les variables locales dans la fonction appelée ou dans la fonction appelante ne sont pas accessibles entre les fonctions (pour rappelle, une variable est accessibles uniquement dans sa portee).+Lorsque vous appelez une fonction, les variables locales dans la fonction appelée ou dans la fonction appelante ne sont pas accessibles entre les fonctions (pour rappel, une variable est accessible uniquement dans sa portée).
  
 <code cpp> <code cpp>
Ligne 21: Ligne 21:
 </code> </code>
  
-Il est donc nécessaire d'avoir un mécanisme pour de pouvoir partager des informations entre une fonction et le reste du code. Cela est réalisé via les paramètres de fonction. Pour rappel, la syntaxe générale d'une fonction est la suivante :+Il est donc nécessaire d'avoir un mécanisme pour pouvoir partager des informations entre une fonction et le reste du code. Cela est réalisé via les paramètres de fonction. Pour rappel, la syntaxe générale d'une fonction est la suivante :
  
 <code> <code>
Ligne 29: Ligne 29:
 </code> </code>
  
-Une fonction va donc pouvoir recevoir zéro, un ou plusieurs paramètres en entrées et zéro ou un paramètre en sortie. Pour commencer, vous allez voir les fonctions qui ne prennent que des paramètres en entrée, les paramètres de sortie seront vu ensuite.+Une fonction va donc pouvoir recevoir zéro, un ou plusieurs paramètres en entrée et zéro ou un paramètre en sortie. Pour commencer, vous allez voir les fonctions qui ne prennent que des paramètres en entrée, les paramètres de sortie seront vus ensuite.
  
 ===== Fonction avec un seul paramètre en entrée ===== ===== Fonction avec un seul paramètre en entrée =====
Ligne 41: Ligne 41:
 Par exemple, pour une fonction qui prend un entier et une autre qui prend une chaîne de caractères. Par exemple, pour une fonction qui prend un entier et une autre qui prend une chaîne de caractères.
  
-<code>+<code cpp>
 void f(int i) { void f(int i) {
     ...     ...
Ligne 51: Ligne 51:
 </code> </code>
  
-Pour la fonction ''f'', le paramètre est ''int i'', qui est déclaré avec un type ''int'' et une identifiant ''i''. Même chose pour ''g'', qui contient un paramètre de type ''std::string'' et qui s'appelle ''s''.+Pour la fonction ''f'', le paramètre est ''int i'', qui est déclaré avec un type ''int'' et un identifiant ''i''. Même chose pour ''g'', qui contient un paramètre de type ''std::string'' et qui s'appelle ''s''.
  
 En pratique, un paramètre s'utilise de la même façon qu'une variable locale (en particulier, un paramètre suit les mêmes règles concernant la portée et la durée de vie : vous pouvez utiliser un paramètre dès qu'il est déclaré et jusqu'à la fin de la fonction). En pratique, un paramètre s'utilise de la même façon qu'une variable locale (en particulier, un paramètre suit les mêmes règles concernant la portée et la durée de vie : vous pouvez utiliser un paramètre dès qu'il est déclaré et jusqu'à la fin de la fonction).
Ligne 57: Ligne 57:
 Par exemple, pour afficher les valeurs des paramètres des fonctions ''f'' et ''g''. Par exemple, pour afficher les valeurs des paramètres des fonctions ''f'' et ''g''.
  
-<code>+<code cpp>
 void f(int i) { void f(int i) {
     std::cout << i << std::endl;     std::cout << i << std::endl;
Ligne 69: Ligne 69:
 Le dernier point à voir est comment appeler une fonction qui prend un paramètre. Pour cela, vous devez donner une valeur entre les parenthèses lors de l'appel de la fonction (cette valeur s'appelle un argument dans un appel de fonction). Une valeur peut être une variable (constante ou non), une littérale ou une expression. Le dernier point à voir est comment appeler une fonction qui prend un paramètre. Pour cela, vous devez donner une valeur entre les parenthèses lors de l'appel de la fonction (cette valeur s'appelle un argument dans un appel de fonction). Une valeur peut être une variable (constante ou non), une littérale ou une expression.
  
-Il existe différents modes de passage de paramètres, qui seront vu dans la suite. Chaque mode accepte ou non certaines types de valeurs. Pour le moment, le mode de passage de paramètre vu est le "passage par valeur", ce qui autorise l'utilisation de n'importe quel type de valeur.+Il existe différents modes de passage de paramètres, qui seront vus dans la suite. Chaque mode accepte ou non certaines types de valeurs. Pour le moment, le mode de passage de paramètre vu est le "passage par valeur", ce qui autorise l'utilisation de n'importe quel type de valeur.
  
 Par exemple, pour appeler une fonction qui prend un paramètre : Par exemple, pour appeler une fonction qui prend un paramètre :
Ligne 79: Ligne 79:
 Avec le code d'exemple précédent, vous pouvez donc écrire : Avec le code d'exemple précédent, vous pouvez donc écrire :
  
-<code>+<code cpp>
 #include <iostream> #include <iostream>
  
Ligne 126: Ligne 126:
 Il existe deux termes qui sont proches, mais qui ont un sens légèrement différent : "paramètre" et "argument". Dans la déclaration de la fonction, vous trouvez des "paramètres de fonction". Dans l'appel de fonction, ce sont des "arguments de fonction". Il existe deux termes qui sont proches, mais qui ont un sens légèrement différent : "paramètre" et "argument". Dans la déclaration de la fonction, vous trouvez des "paramètres de fonction". Dans l'appel de fonction, ce sont des "arguments de fonction".
  
-<code>+<code cpp>
 void f(paramètres...) { void f(paramètres...) {
 } }
Ligne 136: Ligne 136:
 </code> </code>
  
-Beaucoup de personne confondent les deux notions et cela n'est généralement pas problématique. Mais c'est souvent à ce genre de petits détails que l'on reconnait un développeur qui connait son sujet.+Beaucoup de personnes confondent les deux notions et cela n'est généralement pas problématique. Mais c'est souvent à ce genre de petits détails que l'on reconnait un développeur qui connait son sujet.
 </note> </note>
  
Ligne 150: Ligne 150:
 Il n'y a pas de limite théorique dans la norme C++ sur le nombre de paramètres que vous pouvez écrire (__A vérifier__). Par contre, les compilateurs imposent en général une limite. Et de toute façon, une fonction qui prend trop de paramètres deviendra difficilement lisible et c'est généralement le signe qu'il y a un problème d'organisation dans le code. Il n'y a pas de limite théorique dans la norme C++ sur le nombre de paramètres que vous pouvez écrire (__A vérifier__). Par contre, les compilateurs imposent en général une limite. Et de toute façon, une fonction qui prend trop de paramètres deviendra difficilement lisible et c'est généralement le signe qu'il y a un problème d'organisation dans le code.
  
-Par exemple, pour écrire une fonction qui prendre en paramètre un entier et une chaîne :+Par exemple, pour écrire une fonction qui prend en paramètre un entier et une chaîne :
  
 <code cpp> <code cpp>
Ligne 159: Ligne 159:
 </code> </code>
  
-Une fonction qui prend plusieurs paramètres s'appelle en donnant la liste des arguments, séparés aussi par des virgules. Chaque argument est indépendant, vous pouvez mélanger des variables, des constantes, des littérales, des expressions, selon ce qui est autorisé pour chaque paramètre (selon de le mode).+Une fonction qui prend plusieurs paramètres s'appelle en donnant la liste des arguments, séparés aussi par des virgules. Chaque argument est indépendant, vous pouvez mélanger des variables, des constantes, des littérales, des expressions, selon ce qui est autorisé pour chaque paramètre (selon le mode).
  
 <code cpp> <code cpp>
Ligne 167: Ligne 167:
 <note>**std::pair, std::tuple, structures de données** <note>**std::pair, std::tuple, structures de données**
  
-Même si un paramètre correspond à un type, rien n'interdit que ce soit un type complexe, comme par exemple une ''std::pair'', un ''std::tuple'', ou une structure de données. Chacun de ces types peut contenir plusieurs autres types, ce qui permet en pratique de passer en paramètres de fonction autant de types que vous souhaitez.+Même si un paramètre correspond à un type, rien n'interdit que ce soit un type complexe, comme par exemple un ''std::pair'', un ''std::tuple'', ou une structure de données. Chacun de ces types peut contenir plusieurs autres types, ce qui permet en pratique de passer en paramètres de fonction autant de types que vous souhaitez.
  
-Il faut donc éviter de passer trop d'information à une fonction et faire en sorte que les paramètres aient une cohérence entre eux. Par exemple, ''std::string'' est une structure de données complexe, qui contient d'autres information en interne. Mais cela ne pose pas de problème, puisque ce type est manipulé comme un tout cohérent, sans avoir besoin de connaître ce qu'il contient exactement. Seul ce que représente ce type (une chaîne de caractères) est important pour comprendre le sens de la fonction.+Il faut donc éviter de passer trop d'information à une fonction et faire en sorte que les paramètres aient une cohérence entre eux. Par exemple, ''std::string'' est une structure de données complexe, qui contient d'autres informations en interne. Mais cela ne pose pas de problème, puisque ce type est manipulé comme un tout cohérent, sans avoir besoin de connaître ce qu'il contient exactement. Seul ce que représente ce type (une chaîne de caractères) est important pour comprendre le sens de la fonction.
  
-Avec ''std::pair'' et ''std::tuple'', la situation est un peu différente des structures de données. En utilisant ces types, vous pouvez passer n'importe quelles informations, même des informations qui n'ont pas de lien logique entre elles. Même si cela semble être une plus grande liberté, cela nuit en fait à la compréhension du code. Il est donc assez rare de trouver des fonctions utilisant ''std::pair'' et ''std::tuple'' en paramètres. la place, il est préférable de créer une structure de données, qui aura un nom explicite et facilitera la compréhension du code.+Avec ''std::pair'' et ''std::tuple'', la situation est un peu différente des structures de données. En utilisant ces types, vous pouvez passer n'importe quelles informations, même des informations qui n'ont pas de lien logique entre elles. Même si cela semble être une plus grande liberté, cela nuit en fait à la compréhension du code. Il est donc assez rare de trouver des fonctions utilisant ''std::pair'' et ''std::tuple'' en paramètres. À la place, il est préférable de créer une structure de données, qui aura un nom explicite et facilitera la compréhension du code.
 </note> </note>
  
Ligne 218: Ligne 218:
 </code> </code>
  
-Le compilateur indique qu'il ne trouve pas de fonction qui s'appelle ''f'' et dont les paramètres sont compatible avec l'appel ''f(123)'' ("no matching function"). Il indique à la ligne suivante qu'il connait une fonction ''f'' qui pourrait être candidate ("candidate function"), mais qui prend zéro argument ("requires 0 arguments"), alors que l'appel utilise un argument ("but 1 was provided").+Le compilateur indique qu'il ne trouve pas de fonction qui s'appelle ''f'' et dont les paramètres sont compatibles avec l'appel ''f(123)'' ("no matching function"). Il indique à la ligne suivante qu'il connait une fonction ''f'' qui pourrait être candidate ("candidate function"), mais qui prend zéro argument ("requires 0 arguments"), alors que l'appel utilise un argument ("but 1 was provided").
  
 Pour l'appel de la fonction ''g'', le message est le suivant : Pour l'appel de la fonction ''g'', le message est le suivant :
Ligne 237: Ligne 237:
 ==== Correspondance entre les types ==== ==== Correspondance entre les types ====
  
-En plus d'avoir le nombre d'arguments dans un appel de fonction qui doit correspondre au nombre de paramètres déclarés dans une fonction, il faut aussi que les types soient exactement les mêmes ou être implicitement convertible.+En plus d'avoir le nombre d'arguments dans un appel de fonction qui doit correspondre au nombre de paramètres déclarés dans une fonction, il faut aussi que les types soient exactement les mêmes ou être implicitement convertibles.
  
 Un type est "implicitement convertible" (sous entendu "par le compilateur") lorsque le compilateur connaît une conversion entre les types et qu'il a le droit de réaliser automatiquement cette conversion. Un type est "implicitement convertible" (sous entendu "par le compilateur") lorsque le compilateur connaît une conversion entre les types et qu'il a le droit de réaliser automatiquement cette conversion.
Ligne 251: Ligne 251:
  
 int main() { int main() {
-    f(123);     // conversion de int entre double+    f(123);     // conversion de int en double
     g("hello"); // conversion de const char* en string     g("hello"); // conversion de const char* en string
 } }
Ligne 290: Ligne 290:
 Notez que le compilateur fait la différence entre la conversion d'une littérale (//-Wliteral-conversion//) et la conversion d'une valeur réelle (//-Wfloat-conversion//). Le résultat de ces arrondis est visible dans le résultat affiché, puisque seules les parties entières sont conservées. Notez que le compilateur fait la différence entre la conversion d'une littérale (//-Wliteral-conversion//) et la conversion d'une valeur réelle (//-Wfloat-conversion//). Le résultat de ces arrondis est visible dans le résultat affiché, puisque seules les parties entières sont conservées.
  
-Pour terminer, lorsque les types des arguments et des paramètres ne sont pas du tout compatible, le compilateur indique une erreur spécifique (//no known conversion//).+Pour terminer, lorsque les types des arguments et des paramètres ne sont pas du tout compatibles, le compilateur indique une erreur spécifique (//no known conversion//).
  
 <code cpp main.cpp> <code cpp main.cpp>
Ligne 320: Ligne 320:
 ===== Retour de fonction ===== ===== Retour de fonction =====
  
-Le paramètre de retour de fonction est une valeur qui est transmission uniquement depuis la fonction vers le code appelant. Pour rappel, la signature générale d'une fonction qui retourne une valeur est la suivante :+Le paramètre de retour de fonction est une valeur qui est transmise uniquement depuis la fonction vers le code appelant. Pour rappel, la signature générale d'une fonction qui retourne une valeur est la suivante :
  
 <code> <code>
Ligne 359: Ligne 359:
 <note>**Fonction pure** <note>**Fonction pure**
  
-Une fonction similaire au dernier code, qui prend uniquement des paramètres en entrée sans les modifier, puis retourne une valeur, est appelée une fonction pure en programmation fonctionnelle. Cela aura un intérêt particulier, en particulier pour comprendre le comportement d'une fonction et écrire des tests sur cette fonction. Cela sera vu dans le chapitre sur les tests unitaires.+Une fonction similaire au dernier code, qui prend uniquement des paramètres en entrée sans les modifier, puis retourne une valeur, est appelée une fonction pure en programmation fonctionnelle. Cela aura un intérêt particulier, notamment pour comprendre le comportement d'une fonction et écrire des tests sur cette fonction. Cela sera vu dans le chapitre sur les tests unitaires.
  
 Mais dans de nombreux cas, une fonction ne sera pas pure. Une fonction deviendra impure si elle : Mais dans de nombreux cas, une fonction ne sera pas pure. Une fonction deviendra impure si elle :
  
-  * modifie les paramètres en entrée (ce qui est possible en utilisant des indirections, qui seront vu dans le chapitre suivant) ;+  * modifie les paramètres en entrée (ce qui est possible en utilisant des indirections, qui seront vues dans le chapitre suivant) ;
   * en accédant à des variables externes à la fonction (des variables globales).   * en accédant à des variables externes à la fonction (des variables globales).
  
-La simple utilisation de ''std::cout'' est suffisant pour rendre une fonction impure.+La simple utilisation de ''std::cout'' est suffisante pour rendre une fonction impure.
 </note> </note>
  
-La valeur retournée par une fonction est directement accessible dans la code appelant la fonction. L'appel de la fonction peut être directement utilisé comme valeur, ce qui permet de l'affecter à une variable ou de l'utiliser dans une expression. (En fait, un appel de fonction EST une expression).+La valeur retournée par une fonction est directement accessible dans le code appelant la fonction. L'appel de la fonction peut être directement utilisé comme valeur, ce qui permet de l'affecter à une variable ou de l'utiliser dans une expression. (En fait, un appel de fonction EST une expression).
  
 <code cpp main.cpp> <code cpp main.cpp>
Ligne 386: Ligne 386:
 </code> </code>
  
-Une fonction qui retourne une valeur doit obligatoirement avoir au moins un ''return''. Si ce n'est pas le cas, le compilateur produit un message d'erreur.+Une fonction qui retourne une valeur doit obligatoirement avoir au moins un ''return''. Si ce n'est pas le cas, le compilateur produit un message d'erreur :
  
 <code> <code>
Ligne 422: Ligne 422:
 Un cas particulier avec la fonction ''main'' : vous avez peut être réalisé que la signature de cette fonction indique qu'elle doit retourner une valeur entière ''int''. Mais dans les codes d'exemple de cours, le mot-clé ''return'' n'a jamais été utilisé jusqu'à présent. Un cas particulier avec la fonction ''main'' : vous avez peut être réalisé que la signature de cette fonction indique qu'elle doit retourner une valeur entière ''int''. Mais dans les codes d'exemple de cours, le mot-clé ''return'' n'a jamais été utilisé jusqu'à présent.
  
-La raison est que la fonction ''main'' est la seule exception à cette obligation de toujours avoir au moins un ''return'' dans une fonction qui retourne une valeur. Dans la cas de la fonction ''main'', si ''return'' n'est pas présent, la fonction ''main'' retourne par défaut la valeur 0 (qui indique que le programme s'est déroulé correctement).+La raison est que la fonction ''main'' est la seule exception à cette obligation de toujours avoir au moins un ''return'' dans une fonction qui retourne une valeur. Dans le cas de la fonction ''main'', si ''return'' n'est pas présent, la fonction ''main'' retourne par défaut la valeur 0 (qui indique que le programme s'est déroulé correctement).
 </note> </note>
  
parametres_arguments.1526556561.txt.gz · Dernière modification: 2018/05/17 13:29 par gbdivers