Mitől függ, hogy egy programnyelvben függvények, parancsok, vagy más kifejezések vannak?
Mitől függ, hogy miket használ a programnyelv?
Kb. hasonló feladatot végző dolgokra, mért nem mindegy, hogy függvényt, vagy parancsot, vagy valami mást mondunk?
Az adott programozási nyelv terminológiájától függ, bár parancsoknak tényleg nem szoktuk hívni őket. Régen, Basicben szubrutinnak hívtuk azokat az eljárásokat, amik nem adtak vissza értéket, és függvények azokat, amiket igen. De például C-ben egyáltalán nem használjuk a szubrutint, mert ott nincs ilyen. OOP környezetben az osztályhoz tartozó eljárásokat általában metódusnak hívjuk, de például a bővítőfüggvényeket (már ha támogatja őket az adott nyelv) exetnsion methodnak vagy extension functionnek.
De például egyes nyelvek nem engedik meg, hogy az interfészekben metódus implementáció legyen, más nyelvek engedik, megint más nyelvek pedig szintén megengedik, de akkor már mixinnek hívják őket, nem interfészeknek.
"De például C-ben egyáltalán nem használjuk a szubrutint, mert ott nincs ilyen."
Dehogy nincs. Ezek a void tip. függvények.
#5
Nem, a void típusú függvénynek van visszatérési értéke, ez a void. Ez technikailag más, mint a Basic-féle szubrutin.
Dehogy más.
A C tervezésekor az egyszerűség volt a szempont, mivel olyan gépen használták, amiben arcpirítóan kevés volt a memória. Valami 4 kWord, 18 bit szószélességen, ha jól emlékszem.
Ezért is olyan a nyelv, amilyen. Sok operátor, kevés, rövid (eredetileg 19 db) kulcsszó. Na és ennek oka az is, hogy az eljárások nem kaptak külön szerkezetet, hanem a függvények visszatérési értékét, ami ugye bármi lehetett, egyszerűen nem használták fel.
Később ezek a függvénynek "álcázott" procedúrák tipizálva lettek és, most jön a csavar, un. void (érvénytelen) tipusú függvényekben kaptak helyet.
A fizikai megvalósítás ennél azért bonyolultabb, de a lényeg ez.
#7
A különbséget úgy értem, hogy egy Basic interpreter nem is vizsgálja, hogy volt-e a szubrutinnak visszatérési értéke, mert definíció szerint nem is lehet.
C-ben, ha pl. int-et ad vissza függvényed, az az eax regiszterbe kerül. De ha ezt elfelejted, és írsz egy ilyet:
#include<stdio.h>
int add(int a, int b)
{
__int c = a + b;
}
int main(void)
{
__int res = add(3, 2);
__return 0;
}
Akkor az add függvény visszatérési értéke undefined behavior lesz, míg ha ugyanezt voiddal írod meg, így:
void add(int a, int b)
{
__int c = a + b;
}
Akkor a fordító hibát fog jelezni (hogy a void értékét nem használhatod fel). A fordító vizsgálja a visszatérési értéket, tehát a visszatérési érték megadása vagy nem megadása fontos, akkor is, ha az void. Ilyen értelemben mondom azt, hogy a void függvénynek is van visszatérési értéke, és az void. Csak a nyelv szempontjából, a generált kód szempontjából nincs. A fordító valóban figyelmen kívül hagyja a void függvény eredményét, bár én láttam már olyan ARM-s fordítót, ami void esetén eax-ban visszaadott egy 0-át (pont úgy, mint ha int lenne a visszatérési érték).
De szerintem ha bekapcsolsz egy magasabb optimalizációs szintet (-O2 vagy -O3), akkor a fordító inline függvényként generálja le az add függvényt.
Egy nyelvet nem feltétlenül szerencsés valamilyen fordítójának implementációja felől vizsgálni.
Itt a szegedi egyetem progalap c. tárgy anyaga:
Ezen alábbi szerepel:
void main(){
// void - Ez egy adatot tárolni képtelen típus, többek között eljárásokhoz használatos
int egesz; // Egy egyszavas (esetünkben 32 bites - 4 bájtos) előjeles egész szám
// Műveletek: +, -, *, /, %, ahol a / az egészosztás egészrésze, a % az egészosztás maradéka
char karakter; // Egy egybájtos, előjeles, vagy előjeltelen egész szám. Jól használható szöveges karakterek tárolására is, ascii-kód segítségével.
float valos1; // Egy egyszavas lebegőpontos szám
// Műveletek: +, -, *, /
double valos2; // Annyiban különbözik a float-tól, hogy 8 bájtos
// Logikai és szöveges típus külön nincs, azokat máshogy kell megvalósítani. (Későbbi gyakorlaton)
}
Az általad említett BASIC féle szubrutin és a C nyelv void tipusú függvényei közötti különbség annyi, hogy a BASIC nem pakol a verembe semmiféle visszatérési értéket, míg a C, bár pakol, de nem használja fel.
Tehát, a függvényeket mi célból is írjuk?
Hát hogy megkapjuk a visszatérési értéküket. Na de ha azt fel sem használjuk, akkor mi értelme a dolognak? Hát az, hogy a cél áttevődik a visszatérési értékről a függvény beltartalmára. Annak végrehajtása válik céllá.
A függvények írásának célja a visszatérési érték megszerzése. Aztán, hogy ez miként valósul meg (4*2 vagy 2+2+2+2, vagy 2+2*2), az másodlagos. A hangsúly a visszakapott értéken van.
A procedúrák írásának célja a bennük lévő utasításhalmaz végrehajtása. A hangsúly itt a beltartalom végrehajtásán van.
A lényeget jobban megragadva, a void tip. függvények nem függvények, hanem eljárások.
"Az általad említett BASIC féle szubrutin és a C nyelv void tipusú függvényei közötti különbség annyi, hogy a BASIC nem pakol a verembe semmiféle visszatérési értéket, míg a C, bár pakol, de nem használja fel."
Ez alapvetően így is van, és nem is mondom azt, hogy nem így lenne. De a nyelv (és csupán a nyelv, mármint a szabvány C nyelv) szempontjából van különbség, még ha a háttérben ugyanaz történik is. Ha azt mondom neked, hogy "töltsd meg a poharat félig vízzel" vagy azt, hogy "engedj 2dl-t vizet a pohárba", te mindkét ugyanazt fogod csinálni, csak az utasítás volt más.
Ilyen értelemben más a void-ot visszaadó függvény és a szubrutin, én csak ezt akartam mondani.
Kapcsolódó kérdések:
Minden jog fenntartva © 2024, www.gyakorikerdesek.hu
GYIK | Szabályzat | Jogi nyilatkozat | Adatvédelem | Cookie beállítások | WebMinute Kft. | Facebook | Kapcsolat: info(kukac)gyakorikerdesek.hu
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!