Fonction variadique
En programmation informatique, une fonction variadique est une fonction d'arité indéfinie, c'est-à -dire qui accepte un nombre variable de paramètres.
De nombreuses opérations mathématiques et logiques peuvent se représenter sous forme de fonctions variadiques. Par exemple, l'addition de nombres ou la concaténation de chaînes de caractères peuvent s'appliquer à un nombre arbitraire d'opérandes.
Implémentations
C
Le langage C permet la définition de fonctions variadiques.
Les exemples les plus connus sont les fonctions standard d'entrée-sortie printf
et scanf
.
La récupération des arguments se fait grâce au type va_list
et aux macros va_start()
, va_arg()
et va_end()
de <stdarg.h>
. La fonction doit alors trouver un moyen de connaître le type des arguments qui lui ont été fournis, ceux-ci étant choisis par l'utilisateur. Néanmoins, le prototype d'une fonction variadique doit comporter au moins un paramètre muet dont le type est connu.
Exemple : la fonction suivante illustre l'utilisation de <stdarg.h>
.
#include <stdio.h>
#include <stdarg.h>
/* Renvoie la moyenne des valeurs réelles passées en
paramètres. Le premier paramètre, le nombre de valeurs,
doit ĂŞtre strictement positif. Les suivants doivent ĂŞtre
des nombres réels (de type float ou double, pas int) */
double moyenne(int nb_valeurs, double valeur1, ...)
{
double somme = valeur1;
va_list params; // pointeur de la liste des paramètres
va_start(params, valeur1); // initialise le pointeur grâce
// au dernier paramètre fixe
for (int i = 1 ; i < nb_valeurs ; ++i) {
// récupérer le paramètre suivant de la liste:
double valeur_suiv = va_arg(params, double);
somme += valeur_suiv;
}
va_end(params); // fermeture de la liste
return somme / nb_valeurs;
}
int main(void)
{ // exemple d'utilisation :
printf ("%.3f\n", moyenne(3, 14.5, 18.0, 17.5)); // affiche 16.667
return 0;
}
La fonction suivante écrit les données fournies sur l'entrée standard, les types étant décrits dans une chaîne de format (comme avec printf
[1]) :
#include <stdarg.h> /* Pour va_list */
#include <stdio.h> /* Pour printf */
/* À noter que <stdio.h> inclut stdarg.h */
void afficher (const char *format, const char *espace, ...)
{
/* Liste des arguments */
va_list args;
/* Initialisation, à partir du dernier paramètre connu */
va_start (args,espace);
/* Parcours de la chaîne de format et affichage des données */
int i;
for (i=0; format[i]; i++)
switch (format[i])
{
/* Note au niveau des conversions :
* – les arguments de type char ou short sont automatiquement convertis en int ;
* – les arguments de type float sont automatiquement convertis en double.
*/
case 'C' : case 'c' :
printf ("%c%s",va_arg(args,int),espace);
break;
case 'D' : case 'd' :
printf ("%d%s",va_arg(args,int),espace);
break;
case 'E' :
printf ("%E%s",va_arg(args,double),espace);
break;
case 'e' :
printf ("%e%s",va_arg(args,double),espace);
break;
case 'F' : case 'f' :
printf ("%f%s",va_arg(args,double),espace);
break;
case 'G' :
printf ("%G%s",va_arg(args,double),espace);
break;
case 'g' :
printf ("%g%s",va_arg(args,double),espace);
break;
case 'H' :
printf ("%X%s",va_arg(args,int),espace);
break;
case 'h' :
printf ("%x%s",va_arg(args,int),espace);
break;
case 'O' : case 'o' :
printf ("%o%s",va_arg(args,int),espace);
break;
case 'P' : case 'p' :
printf ("%p%s",va_arg(args,void*),espace);
break;
case 'S' : case 's' :
printf ("%s%s",va_arg(args,char*),espace);
break;
default : ;
}
/* Fermeture */
va_end (args);
}
/* Exemple d'utilisation */
int main (void)
{
afficher ("doHefGcsp"," ",9572,9572,9572,6569.28,6569.28,6569.28,'
Ce programme affiche :
9572 22544 2564 6.569280e+003 6569.280000 6569.28 $ Exemple 00000000
Java
Les méthodes variadiques existent en Java depuis la version 5. Un paramètre (le dernier, s'il y en a plusieurs) peut être déclaré variadique en ajoutant trois points de suspension après son type. Ce paramètre sera en fait un tableau dont les éléments, du type déclaré, prendront les valeurs des paramètres effectifs multiples.
Exemple :
double moyenne(double... valeurs)
{
double somme = 0;
for (double valeur : valeurs)
somme += valeur;
return somme / valeurs.length;
}
L'invocation de cette méthode pourra se faire avec n'importe quel nombre de paramètres :
m1 = moyenne(14.5, 17, 15); // m1 = 15.5
m2 = moyenne(10); // m2 = 10.0
m3 = moyenne(); // m3 = NaN
PHP
PHP, depuis la version 4, permet de définir des fonctions variadiques. Au sein d'une telle fonction, les paramètres peuvent être obtenus à l'aide des fonctions func_num_args()
, func_get_arg()
et func_get_args()
[2].
Exemple de code :
// Avant PHP 5.3 :
function somme() {
$args = func_get_args();
return array_sum($args);
}
// Syntaxe autorisée depuis PHP 5.3 :
function somme() {
return array_sum(func_get_args());
}
somme(2, 2); // renvoie 4
Depuis la version 5.6[3], il est possible (et préférable) d'utiliser l'opérateur ...
, appelé splat operator :
function somme(...$termes) {
return array_sum($termes);
}
De plus, depuis la version 7.0[4], il est possible de spécifier le type des paramètres :
function sommeEntiers(int ...$termes) {
return array_sum($termes);
}
python
Exemple de code :
#!/usr/bin/env python
#-*- coding: utf-8 -*-
# Python 3.7
def moyenne(*argv) -> float:
somme : float = 0
for arg in argv:
somme = somme + arg
return somme / len(argv)
if __name__ == '__main__':
# exemple d'utilisation :
print(moyenne(14.5, 18.0, 17.6)) # affiche 16.7
Tcl
Le langage Tcl] permet la définition de fonctions variadiques depuis le début.
Exemple de code :
proc moyenne args {
if {[set n [llength $args]] == 0} {return 0}
expr {[tcl::mathop::+ {*}$args] / double($n)}
}
moyenne 1 2 3 4 5 6 7 8 9 ; # affiche 5.0
moyenne 1 2 3 4 5 ; # affiche 3.0
moyenne 1 2 ; # affiche 1.5
Notes et références
- Page de manuel de
printf
- (en) Function arguments : Variable-length argument lists, dans le manuel PHP.
- (en) PHP 5.6 New features : Variadic functions via
...
, dans le manuel PHP. - (en) PHP 7.0 New features : Scalar type declarations, dans le manuel PHP.
Lien externe
- Variable Argument Functions, un tutoriel sur les fonctions variadiques en C++