A paraméter a programozásban egy függvény által elfogadott argumentum. Az "argumentum" kifejezés azt jelenti, hogy pontosan mit adtak át és melyik függvénynek , valamint a paramétert - azt, hogy a függvény milyen minőségben alkalmazta ezt. Vagyis a hívó kód átadja az argumentumot egy olyan paraméternek, amely a függvényspecifikáció egyik tagjában van definiálva.
Fontos megkülönböztetni:
Példa C nyelven :
// Funkció leírás. int a - formális paraméter, előfordulhat, hogy a paraméter neve hiányzik. int myfunction ( int a ); // Funkció meghatározása. int b - formális paraméter, előfordulhat, hogy a paraméter neve nem egyezik a függvény deklarálásakor megadottal. int myfunction ( int b ) { return 0 ; } int main () { int c = 0 ; myfunction ( c ); // Funkcióhívás. c a tényleges paraméter. return 0 ; }A formális és tényleges paraméterek használatának szemantikáját kiértékelési stratégiának nevezzük . Egy adott értékelési stratégia megszabja , hogy egy függvény argumentumait (módszer, művelet, reláció) mikor kell kiértékelni, és milyen értékeket kell átadni. Nagyon sok különböző számítási stratégia létezik.
Megjegyzés - az imperatív programozói közösségben„ paraméterátadás ” kifejezés használata sok programozási nyelv esetében nem teljesen helyes - például a Haskell nyelvben használt szükséghívás esetén a paraméter használható a függvénytörzsben , de soha nem adható át a hívás minden esetére, sőt teljesen kizárható a kapott gépi kódból.
A leggyakrabban említett értékelési stratégiák a call by value és call by reference , de ezeknek a kifejezéseknek a tényleges használata nem mindig megfelelő. Például a Java nyelvi közösségben azt mondják, hogy " A Java hívást használ, ahol az "érték" egy objektumhivatkozás ", a Ruby nyelvi közösségben pedig azt mondják, hogy " A Ruby a hivatkozás alapján hívást használ ", de valójában mindkét nyelv használja a referencia - hívás stratégiát. .call -by -sharing ) [3] [4] . Sok nyelv, mint például a C , nem rendelkezik hívó-referencia mechanizmussal, de lehetővé teszi annak szimulálását az érték szerinti hívás szemantikán belül hivatkozási típusok , különösen mutatók segítségével . Ez utóbbi esetben az ilyen nyelvű közösségekben gyakran mondják, hogy " a nyelv két értékelési stratégiát támogat ", valamint " mutatónkénti hívást " vagy " cím szerinti hívást ".
A gyakorlatban sok ipari nyelv ( Java , C# ) számítási modellje „ megemlítéskor/hivatkozási hívás ” stratégiára redukálódik . Egyes régebbi nyelvek, különösen a nem biztonságos nyelvek, mint például a C++ , több különböző hívási mintát kombinálnak, beleértve az egzotikusakat is, mint például a hívás a hivatkozásonként az állandóra . Történelmileg a hívás érték szerint és a hívás név szerint az 1950 -es évek végén létrehozott Algol-60- ig nyúlik vissza . Csak a tiszta funkcionális nyelvek, mint például a Clean és a Haskell használják a call - by - need kifejezést , amelyet gyakran azonosítanak (ami szintén nem teljesen helyes) a lusta kiértékeléssel .
A paraméter hivatkozással történő átadása azt jelenti, hogy nem magát az értéket másoljuk , hanem az eredeti változó címét (mint a paraméter címenkénti átadása esetén), azonban a szintaxist úgy használjuk, hogy a programozónak ne kelljen a dereferencia műveletet , és közvetlenül kezelheti az ezen a címen tárolt értéket (mint az érték melletti paraméterátadás esetén).
A hivatkozással történő átadás elkerüli az objektum állapotát leíró összes információ másolását (amely lényegesen nagyobb lehet, mint a sizeof(int)), és szükséges a másoláskonstruktor számára .
Ha egy függvény hivatkozással ad vissza értéket (például "return *this;" formában), akkor a hívása használható a hozzárendelési operátor bal oldalán (lásd még : L-kifejezés ).
Ha a hivatkozás alapján történő átadást pontosan a teljesítmény növelésének eszközeként használják, de a paraméter megváltoztatása nem kívánatos, használhatja az átadást egy állandó objektum hivatkozásával.
Példa C++ nyelven : #include <iostream> névtér használata std ; // cout használatához void f ( int x ) { // paraméter átadása értékkel cout << x ; x = 1_ _ cout << x ; } void g ( int * x ) { // paraméter átadása a cout << * x címnek ; * x = 2 ; cout << * x ; } érvénytelen h ( int & x ) { // paraméter átadása hivatkozással cout << x ; x = 3 ; cout << x ; } void i ( const int & x ) { // egy megváltoztathatatlan paraméter átadása referencia couttal << x ; x = 4 ; // Hiba, ami miatt a kód nem fordítódik le cout << x ; } int main () { int x = 0 ; cout << x ; f ( x ); cout << x << " " ; g ( & x ); cout << x << " " ; h ( x ); cout << x << " " ; i ( x ); cout << x ; return 0 ; }Így azt várnánk, hogy a példaprogram kiírja (ha a hibás sort kommentálja) "0010 022 233 333".
Egyes nyelvek (vagy dialektusaik) nem támogatják az áthaladás-hivatkozást, míg mások éppen ellenkezőleg, kizárólag hivatkozással adják át a paramétereket, ami azt a kockázatot jelenti, hogy véletlenül megváltozik a hívó funkció kontextusa.
A Fortran nyelv azt jelenti, hogy a paramétereket kizárólag hivatkozással kell átadni:
Fortran példa :Program:
A PROGRAM PARAMÉTEREI IMPLICIT NINCS EGÉSZ A , B , C A = 7,0 B = 9,0 C = 0,0 100 FORMÁTUM ( 'A =' , I2 , ', B =' , I2 , ', C =' , I3 ) ÍRÁS ( * , 100 ) A , B , C CALL MUL ( A , B , C ) ÍRÁS ( * , 100 ) A , B , C PROGRAM VÉGE MUL ( A , B , C ) EGÉSZ SZEM A , B , C C = A * B VÉG SZUBRUTINNyomtatásra kerül:
A=7, B=9, C=0 A=7, B=9, C=63