Article de reference

fonction variadique

En mathématiques et en programmation informatique , une fonction variadique est une fonction d' arité indéfinie , c'est-à-dire une fonction qui accepte un nombre variable d' arg...

mathématiques et en programmation informatique , une fonction variadique est une fonction d' arité indéfinie , c'est-à-dire une fonction qui accepte un nombre variable d' arguments . La prise en charge des fonctions variadiques varie considérablement d' un langage de programmation à l'autre .

concaténation de chaînes de caractères ou d'autres séquences sont des opérations qui peuvent être considérées comme applicables à un nombre quelconque d'opérandes (même si, formellement, dans ces cas, la propriété associative est appliquée).

Une autre opération implémentée sous forme de fonction variadique dans de nombreux langages est la mise en forme de la sortie. La fonction `format` en CLispde sécurité des types dans certains langages. Par exemple, en C attaques par formatage de chaînes . Cette attaque est possible car la prise en charge des fonctions variadiques par le langage n'est pas sûre au niveau des types : elle autorise la fonction à tenter de dépiler plus d'arguments qu'il n'en a été placé, corrompant ainsi la pile et provoquant un comportement inattendu. De ce fait, le CERT Coordination Center considère les fonctions variadiques en C comme un risque de sécurité majeur.

Dans les langages de programmation fonctionnelle , les fonctions variadiques peuvent être considérées comme complémentaires à la fonction `apply` , qui prend une fonction et une liste/séquence/un tableau comme arguments, et appelle la fonction avec les arguments fournis dans cette liste, lui passant ainsi un nombre variable d'arguments. Dans le langage fonctionnel Haskell , les fonctions variadiques peuvent être implémentées en retournant une valeur d'une classe de types ; si les instances de cette classe sont une valeur de retour finale et une fonction , cela autorise un nombre quelconque d'arguments supplémentaires .sur la réécriture de termes est celui des variables de couverture , ou « hedges » . Contrairement aux fonctions variadiques, qui sont des fonctions avec arguments, les variables de couverture sont elles-mêmes des séquences d'arguments. Elles peuvent également avoir des contraintes (« ne pas prendre plus de 4 arguments », par exemple) au point de ne plus être de longueur variable (comme « prendre exactement 4 arguments ») ; les qualifier de variadiques peut donc induire en erreur. Cependant, il s'agit du même phénomène, et la terminologie est parfois confondue, donnant lieu à des termes tels que « variable variadique » (synonyme de variable de couverture). Il convient de noter la double signification du mot « variable » et la différence entre arguments et variables en programmation fonctionnelle et en réécriture de termes. Par exemple, un terme (fonction) peut avoir trois variables, dont une variable de couverture, ce qui lui permet de prendre trois arguments ou plus (ou deux ou plus si la variable de couverture peut être vide).

Exemples

langage Cdéprécié au profit de celui-ci . En C++, on utilise " , average ( 3 , 1 , 2 , 3 )); return 0 ; }

Cette fonction calcule la moyenne d'un nombre quelconque d'arguments. Notez qu'elle ignore le nombre d'arguments et leurs types. La fonction suppose que les types sont `int`, `int` et `double` `printf` , le nombre et les types des arguments sont déduits d'une chaîne de format. Dans les deux cas, il incombe au programmeur de fournir les informations correctes. (Il est également possible d'utiliser une valeur sentinelle , comme attaque par chaîne de format . Selon le système, même l'utilisation pointeur nul

C23 , le second argument ne sera plus requis et les fonctions variadiques n'auront plus besoin de paramètre nommé avant les points de suspension. Elle initialise l' En C#, les fonctions variadiques sont décrites à l'aide du un raccourci syntaxique pour cette dernière approche.

C++26 , la virgule précédant les points de suspension pouvait être omise. Le C++ autorise également les fonctions variadiques sans paramètres nommés (par exemple, ` void f(...);f`). Cependant, jusqu'à C++26, il n'existait aucun moyen portable d'accéder à ces arguments, car `f` va_startnécessitait le nom du dernier paramètre fixe de la fonction. Depuis C++26, le C++ adopte la forme à un argument de `f` va_start, conforme à C23, et permet d'accéder aux arguments même lorsque la fonction ne possède aucun paramètre fixe.

Les modèles variadiques (packs de paramètres) peuvent également être utilisés en C++ grâce aux expressions de pliage intégrées au langage . Les modèles variadiques constituent la seule méthode sûre pour gérer les fonctions et paramètres variadiques en C++, car ce langage ne prend pas en charge les paramètres variadiques non liés à un modèle, contrairement à Java.

, args )), ...); }int main ( int argc , char * argv []) { fooPrint ( 1 , 3.14f ); // 1 3.14 fooPrint ( "Foo" , 'b' , true , nullptr ); // Foo b true nullptr }

Les normes de codage CERT pour C++ préconisent fortement l'utilisation de modèles variadiques (packs de paramètres) en C++ plutôt que de fonctions variadiques de style C, en raison d'un risque d'utilisation inappropriée moindre. Les modèles variadiques sont le seul moyen d'obtenir des paramètres variadiques typés comme en Java.

Pour contraindre le paramètre à être uniquement de type T(similaire à T... args) en Java, on peut utiliser le concept std::same_as ou std::convertible_to(pour les types qui peuvent être destinés à être convertibles).

Carbon , un langage conçu pour l'interopérabilité avec C++, offre des variades, notamment des extensions de paquets.

Vector((... each ElementType)) { ... var each iter: auto = each vector.Begin(); var result: Vector((... each ElementType)); while (...and each iter != each vector.End()) { result.push_back((... each iter)); ... each iter++; } return result; } "
// Prend un nombre arbitraire de vecteurs avec des types d'éléments arbitraires, et // retourne un vecteur de tuples où le i-ème élément du vecteur est // un tuple des i-èmes éléments des vecteurs d'entrée. fn Zip [ ... each ElementType :! type ]( ... each vector : Vector ( each ElementType )) -> Vector (( ... each ElementType )) { ... var each iter : auto = each vector . Begin (); var result : Vector (( ... each ElementType )); while ( ... and each iter != each vector . End ()) { result . push_back (( ... each iter )); ... each iter ++ ; } return result ; }

Fortran

Depuis la révision Fortran 90, les fonctions et sous-programmes Fortran peuvent accepter des arguments optionnels : la liste des arguments reste fixe, mais ceux qui possèdent l’ !> les 2 derniers arguments sont omis : appel foo ( 1 , 2 , 3.0 ) !< affiche 1 \ 2 \ 3.0 !> les 2e et 4e arguments sont omis : les arguments qui sont positionnés après !> un argument omis doit être passé avec un mot-clé : appel foo ( 1 , c = 3.0 , e = x ) !< affiche 1 \ 3.0 \ 6.0 !> alternativement, la révision Fortran 2023 a introduit le .NIL. pseudo constante !> pour indiquer un argument omis appel foo ( 1 , . NIL ., 3.0 , . NIL ., x ) !< affiche 1 \ 3.0 \ 6.0contientLa sous-routine foo() possède 2 arguments obligatoires et 3 arguments optionnels. Voici son fonctionnement : `subroutine foo ( a , b , c , d , e ) integer , intent ( in ) :: a integer , intent ( in ), optional :: b real , intent ( in ) :: c integer , intent ( in ), optional :: d real , intent ( out ), optional :: e print * , a if ( present ( b )) print * , b print * , c if ( present ( d )) print * , d if ( present ( e )) then e = 2 * c print * , c end if end subroutine`programme de fin

Aller

Les fonctions variadiques en Go peuvent être appelées avec un nombre quelconque d'arguments finaux. // Cette fonction variadique prend un nombre arbitraire d'entiers comme arguments. func sum ( nums ... int ) { fmt.Print ( " La somme de " , nums ) // Également une fonction variadique. total := 0 for _ , num := range nums { total + = num } fmt.Println ( " est " , total ) // Également une fonction variadique. }func main () { // Les fonctions variadiques peuvent être appelées de manière classique avec des arguments individuels. sum ( 1 , 2 ) // "La somme de [1 2] est 3" sum ( 1 , 2 , 3 ) // "La somme de [1 2 3] est 6"// Si vous avez déjà plusieurs arguments dans une tranche, appliquez-les à une fonction variadique // en utilisant func(slice...) comme ceci. nums := [] int { 1 , 2 , 3 , 4 } sum ( nums ... ) // "La somme de [1 2 3 4] est 10" }

Sortir:

Java est disponible comme type générique.

En Java, un paramètre peut être variadique grâce à la notation à points de suspension. Cela équivaut à un tableau, sans pour autant nécessiter de l'encapsuler. Par exemple, `a` String... argset String[] args`b` sont quasiment identiques.

); // raccourci pour printArgs(new String[] {"hello"}) printArgs ( "hello" , "world" ); // raccourci pour printArgs(new String[] {"hello", "world"}) } }

JavaScript

JavaScript ne tient pas compte du type des arguments variadiques. Un argument variadique est indiqué par `var` ..., qui désigne un « paramètre rest » regroupant les arguments dans un tableau.

a + b, 0); } console.log(sum(1, 2, 3)); // 6 console.log(sum(3, 2)); // 5 console.log(sum()); // 0 "
function sum (... nombres ) { return nombres.reduce ( ( a , b ) = > a + b , 0 ); }console.log ( sum ( 1 , 2 , 3 ) ); // 6 console.log ( sum ( 3 , 2 ) ); // 5 console.log ( sum ( ) ) ; // 0

Il est également possible de créer une fonction variadique en utilisant l'objet arguments, bien que celle-ci ne soit utilisable qu'avec les fonctions créées avec le TypeScript , puisque le paramètre rest est un tableau, il est noté comme suit :

a + b, 0); } "
fonction somme ( ...nombres : nombre []) : nombre { return nombres . réduire (( a , b ) => a + b , 0 ); }

TypeScript permet également d'imposer au paramètre rest un nombre exact d'éléments (c'est-à-dire un tuple) :

a + b, 0); } // Forces at least two numbers function sumAtLeastTwo(...numbers: [number, number, ...number[]]): number { return numbers.reduce((a, b) => a + b, 0); } // Forces the first argument to be a string, then anything after function log(...args: [string, ...any[]]) { // ... } "
// Force exactement trois nombres function sumExactlyThree (... numbers : [ number , number , number ]) : number { return numbers . reduce (( a , b ) => a + b , 0 ); }// Force au moins deux nombres function sumAtLeastTwo (... nombres : [ nombre , nombre , ... nombre []]) : nombre { return nombres . reduce (( a , b ) => a + b , 0 ); }// Force le premier argument à être une chaîne de caractères, puis tout ce qui suit. function log (... args : [ string , ... any []]) { // ... }

Lua

Les fonctions Lua peuvent passer des arguments variables à d'autres fonctions de la même manière que d'autres valeurs, grâce au Pascal est normalisé par les normes ISO 7185 (« Pascal standard ») et 10206 (« Pascal étendu »). Aucune des deux formes normalisées de Pascal ne prend en charge les routines variadiques, à l'exception de certaines routines intégrées ( Delphi définit un type de données pouvant être associé au dernier paramètre formel . Dans la définition de la routine, ce type est un tableau d' enregistrements variants . Le membre de ce type de données permet d'inspecter le type de données de l'argument et d'effectuer le traitement approprié. Le compilateur Free Pascal prend également en charge les routines variadiques de Delphi.

Cette implémentation requiert techniquement un seul argument, à savoir un tableau GNU Pascal définit une spécification formelle de paramètres variadique réelle utilisant des points de suspension ( PHP ne tient pas compte du type des arguments variadiques sauf si l'argument est typé.

, 3 ); // TypeError : L’argument 2 passé à sum() doit être de type int (depuis PHP 7.3)

Python

Python ne tient pas compte des types des arguments variadiques.

None: print(args) # args is a tuple (immutable sequence). if __name__ == \"__main__\": foo(1, 2) # args = () foo(1, 2, 3) # arga = (3,) foo(1, 2, 3, \"hello\") # args = (3, \"hello\") "
from typing import Anydef foo ( a : Any , b : Any , * args : Any ]) -> None : print ( args ) # args est un tuple (séquence immuable).if __name__ == "__main__" : foo ( 1 , 2 ) # args = () foo ( 1 , 2 , 3 ) # args = (3,) foo ( 1 , 2 , 3 , "hello" ) # args = (3, "hello")

Les arguments nommés peuvent être stockés dans un dictionnaire.

Any: # function body "
def bar ( * args : Any , ** kwargs : Any ]) -> Any : # corps de la fonction

Notez que même si Raku , les types de paramètres qui créent des fonctions variadiques sont appelés paramètres de tableau slurpy et sont classés en trois groupes :

Slurpy aplati

Ces paramètres sont déclarés avec un seul astérisque ( *) et ils aplatissent les arguments en dissolvant une ou plusieurs couches d'éléments qui peuvent être itérés (c.-à-d. Iterables ).

) # [3 "hello"] foo ( 1 , 2 , 3 , [ 4 , 5 ], [ 6 ]); # [3, 4, 5, 6]

Slurpy non aplati

Ces paramètres sont déclarés avec deux astérisques ( **) et ils n'aplatissent aucun argument itérable dans la liste, mais conservent les arguments plus ou moins tels quels :

); # [3 "bonjour"] barre ( 1 , 2 , 3 , [ 4 , 5 ], [ 6 ]); # [3, [4, 5], [6]]

Slurpy contextuel

Ces paramètres sont déclarés avec un +signe plus (+) et appliquent la « règle de l'argument unique » , qui détermine comment traiter l'argument `slurpy` en fonction du contexte. Autrement dit, si un seul argument est fourni et que cet argument est itérable, il est utilisé pour remplir le tableau de paramètres `slurpy`. Dans tous les autres cas, +@le comportement est identique à celui de `slurpy` **@(c'est-à-dire, une fonction `slurpy` non aplatie).

); # [3 "hello"] zaz ( 1 , 2 , [ 4 , 5 ]); # [4, 5], un seul argument remplit le tableau zaz ( 1 , 2 , 3 , [ 4 , 5 ]); # [3, [4, 5]], se comporte comme **@ zaz ( 1 , 2 , 3 , [ 4 , 5 ], [ 6 ]); # [3, [4, 5], [6]], se comporte comme **@

Rubis

Ruby ne tient pas compte des types des arguments variadiques.

nil` foo(1, 2) # prints `[1, 2]=> nil` "
def foo ( * args ) print (args ) endfoo ( 1 ) # affiche `[1]=> nil`foo ( 1 , 2 ) # affiche `[1, 2]=> nil`

Rouiller

Rust ne prend pas en charge les arguments variadiques dans les fonctions. Il utilise à la place des macros , qui, elles, les prennent en charge. C'est essentiellement pourquoi `f` println!est une macro et non une fonction : elle prend des arguments variadiques pour la mise en forme.

{{ { let val: usize = $e; // Force types to be integers println!(\"{} = {}\", stringify!{$e}, val); } }}; // Decompose multiple `eval`s recursively (eval $e:expr, $(eval $es:expr),+) => {{ calculate! { eval $e } calculate! { $(eval $es),+ } }}; } fn main() { calculate! {\\ eval 1 + 2, eval 3 + 4, eval (2 * 3) + 1 } } "
macro_rules! calculer { // Le modèle pour un seul `eval` ( eval $e : expr ) => {{ { let val : usize = $e ; // Forcer les types à être des entiers println! ( "{} = {}" , stringify! { $e }, val ); } }};// Décomposer plusieurs `eval` récursivement ( eval $e : expr , $( eval $es : expr ), + ) => {{ calculate ! { eval $e } calculate ! { $( eval $es ), + } }}; }fn main () { calculer ! { \ eval 1 + 2 , eval 3 + 4 , eval ( 2 * 3 ) + 1 } }

Rust peut interagir avec le système variadique de C via un fn add ( n : usize , mut args : .. .) -> usize { let mut sum = 0 ; for _ in 0 .. n { sum += args . arg :: < usize > (); } sum }

Scala

); // raccourci pour printArgs(["hello"]) printArgs ( "hello" , "world" ); // raccourci pour printArgs(["hello", "world"]) } }

Rapide

Swift tient compte du type des arguments variadiques, mais le type générique \( names.count ) personnes" ) for name in names { print ( "Bonjour \( name ) , bon \ ( timeOfTheDay ) " ) } }saluer ( heureDeLaJournée : "matin" , noms : "Joseph" , "Clara" , "William" , "Maria" )// Résultat : // Il semble que nous ayons 4 personnes // Bonjour Joseph, bonjour // Bonjour Clara, bonjour // Bonjour William, bonjour // Bonjour Maria, bonjour

Tcl

Une procédure ou lambda Tcl est variadique lorsque son dernier argument estforeach name $args { puts "Bonjour $name, bonjour $timeOfTheDay" } }saluer « matin » « Joseph » « Clara » « William » « Maria »# Résultat : # Il semble que nous ayons 4 personnes # Bonjour Joseph, bonjour # Bonjour Clara, bonjour # Bonjour William, bonjour # Bonjour Maria, bonjour

Plus d articles de Worldlex Wiki

Revenez a l index pour explorer davantage de pages sur l histoire, la science, la culture, la geographie et la societe en francais.

Explorer l index