Il est très fréquent que certains paramètres dune fonction prennent une valeur particulière plus souvent que dautres, ou encore ne servent à rien dans certains cas.
Imaginons par exemple une procédure qui ajoute une chaîne à la fin dune autre. Un tel ajout peut provoquer un débordement, aussi nest-il pas inutile de donner un paramètre indiquant la taille maximale à ne pas dépasser pour la chaîne résultat. Voici une implantation possible dune telle fonction :
char* ajoute(char *dest, const char *ajout, int max) // ajoute la seconde chaîne à la première, sans // dépasser la taille max pour le résultat. { int ld = strlen(dest), la = strlen(ajout); if ( (max > ld +la) || (max <= 0) ) max =0; else la = max -ld -1; if (la > 0) memmove(dest+ld, ajout, la); if (max) *(dest+max) = 0; // zéro final return dest; }
On ignore ici le paramètre max
sil est négatif ou nul, la seconde chaîne est alors recopiée entièrement derrière la première. Si ce paramètre est inférieur à la longueur de dest
la chaîne est simplement tronquée, ajout
ne sert à rien. Voici un exemple dutilisation de cette fonction :
char s1[10] = "Hello! ", s2 = "Comment allez-vous ?"; ajoute(s1, s2, 10);
La chaîne s1
vaut alors "Hello! Com"
, soit 10 caractères, en comptant le zéro final, et remplit donc entièrement la mémoire qui lui est attribuée.
Cependant, dans de nombreux cas, on na pas besoin de préciser un paramètre max
, parce quon est sûr quil ny aura pas débordement. On précise alors une valeur nulle pour max
, qui signifie conventionnellement « toute la place disponible » . Par exemple, dans ce cas :
char tampon[256] = ""; ajoute(tampon, s, 0); ajoute(tampon, s2, 0);
De tels cas sont très fréquents en pratique. Mais on en voit clairement linconvénient : il faut préciser un troisième argument inutile, dont la valeur conventionnelle doit être retenue par coeur (cela peut être plus complexe que 0
).
En C++, on peut donner une valeur par défaut à un argument de fonction, comme ceci :
char *ajoute(char *dest, const char *ajout, int max = 0 ) // reste identique...
Dans ce cas, on peut appeler la fonction sans préciser ce paramètre, qui prend alors la valeur par défaut indiquée :
char tampon[256] = ""; ajoute(tampon, s); ajoute(tampon, s2);
est ici équivalent à lécriture précédente, mais plus sobre.
Ces arguments par défaut sont une capacité très intéressante de C++, qui permet des écritures beaucoup plus agréables. On peut ainsi regrouper plusieurs fonctions. Par exemple, il existe deux fonctions de copie dans la librairie <string.h>
(qui est écrite en langage C, non en C++) :
char *strcpy(char *dest, const char *source);
qui recopie entièrement source
dans dest
, que nous connaissons déjà, et :
char *strncpy(char *dest, const char *source, size_t max)
qui copie au plus max
caractères de source
vers dest
. On voit quavec les arguments par défaut, une seule fonction aurait suffi, comme ceci par exemple :
char *strcpy(char *dest, const char *source,
size_t max = 65535);
Une fonction peut avoir plusieurs arguments par défaut, qui peuvent être des expressions constantes de toutes sortes :
void f(int a, double d = 2*Pi, int n = 0); int g(long n = -1, void *p = NULL);
Cependant seuls les derniers arguments peuvent avoir une valeur par défaut, il nest pas possible de faire un mélange :
int h(long n =0, int i, float f =1); // non, mélange!
Dautre part, il nest pas possible de placer des expressions dépendant dautres arguments :
int k(int a, int b = a); // interdit
Pour réaliser cette opération, il faut soit placer une valeur par défaut spéciale constante pour b
, et recopier a
dans b
au début de la fonction quand b
est égal à cette valeur, soit écrire deux versions de la même fonction, ce qui est permis en C++ (voir plus loin).
Nous utiliserons beaucoup dans la suite ces arguments par défaut, qui permettent de simplifier notablement les programmes, en évitant une surcharge de fonctions.
Précédent | Sommaire | Suivant |