Funkcióprototípusok

  • 11/04/2016
  • 3 perc olvasás
    • c
    • v
    • n
    • M
    • g
    • +1

A függvénydeklaráció megelőzi a függvénydefiníciót és megadja a nevét, visszatérési típusát, tárolási osztályát és a függvény egyéb attribútumait. Ahhoz, hogy prototípus legyen, a függvénydeklarációnak meg kell határoznia a függvény argumentumainak típusait és azonosítóit is.

Syntax

declaration:
declaration-specifiers attribute-seqopt init-declarator-listopt ;

/* attribute-seqopt is Microsoft-specific */

declaration-specifiers:
storage-class-specifier declaration-specifiersopt
type-specifier declaration-specifiersopt
type-qualifier declaration-specifiersopt

init-declarator-list:
init-declarator
init-declarator-list , init-declarator

init-declarator:
declarator
declarator = initializer

declarator:
pointeropt direct-declarator

direct-declarator: /* Egy függvénydeklarátor */
direct-declarator ( parameter-type-list ) /* Új stílusú deklarátor */
direct-declarator ( identifier-listopt ) /* Elavult stílusú deklarátor */

A prototípus ugyanolyan formájú, mint a függvénydefiníció, kivéve, hogy a záró zárójelet közvetlenül követő pontosvesszővel zárul, tehát nincs teste. A visszatérési típusnak mindkét esetben meg kell egyeznie a függvénydefinícióban megadott visszatérési típussal.

A függvényprototípusoknak a következő fontos felhasználási módjai vannak:

  • A visszatérési típust olyan függvényeknél állapítják meg, amelyek a int-től eltérő típusokat adnak vissza. Bár a int értékeket visszaadó függvényeknek nincs szükségük prototípusokra, a prototípusok használata ajánlott.

  • Teljes prototípusok nélkül a szabványos átalakítások megtörténnek, de nem történik kísérlet az argumentumok típusának vagy számának a paraméterek számával való összevetésére.

  • A prototípusok a függvényekre mutató mutatók inicializálására szolgálnak, mielőtt a függvények definiálásra kerülnek.

  • A paraméterlista a függvényhívásban szereplő argumentumok és a függvénydefinícióban szereplő paraméterek megfelelésének ellenőrzésére szolgál.

Az egyes paraméterek átalakított típusa határozza meg az argumentumok értelmezését, amelyeket a függvényhívás a veremre helyez. Egy argumentum és egy paraméter közötti típuseltérés a veremre kerülő argumentumok félreértelmezéséhez vezethet. Például egy 16 bites számítógépen, ha egy 16 bites mutatót adunk át argumentumként, majd long paraméterként deklaráljuk, a verem első 32 bitje long paraméterként értelmeződik. Ez a hiba nemcsak a long paraméterrel, hanem az azt követő paraméterekkel is problémákat okoz. Az ilyen jellegű hibákat úgy lehet felderíteni, ha minden függvényhez teljes függvényprototípust deklarálunk.

A prototípus meghatározza egy függvény attribútumait, hogy a definícióját megelőző (vagy más forrásfájlokban előforduló) függvényhívások ellenőrizhetők legyenek argumentumtípus- és visszatérési típus-eltérések szempontjából. Ha például egy prototípusban megadja a static tárolási osztály specifikálót, akkor a függvénydefinícióban is meg kell adnia a static tárolási osztályt.

A teljes paraméterdeklarációk (int a) keverhetők absztrakt deklarátorokkal (int) ugyanabban a deklarációban. Például a következő deklaráció legális:

int add( int a, int );

A prototípus tartalmazhatja az argumentumként átadott minden egyes kifejezés típusát és azonosítóját is. Az ilyen azonosítóknak azonban csak a deklaráció végéig van hatókörük. A prototípus azt is tükrözheti, hogy az argumentumok száma változó, vagy hogy nem adunk át argumentumokat. Ilyen lista nélkül a nem egyezéseket nem lehet felfedni, így a fordító nem tud velük kapcsolatban diagnosztikai üzeneteket generálni. A típusellenőrzéssel kapcsolatos további információkért lásd az Arguments című fejezetet.

A Microsoft C fordítóban a prototípus hatókör mostantól ANSI-kompatibilis, ha a /Za fordítóopcióval fordítjuk. Ez azt jelenti, hogy ha egy struct vagy union címkét deklarál egy prototípuson belül, a címke nem a globális hatókörben, hanem az adott hatókörben kerül beírásra. Például, ha /Za-val fordít az ANSI-megfelelőség érdekében, ezt a függvényt soha nem hívhatja meg anélkül, hogy típusillesztési hibát kapna:

void func1( struct S * );

A kód javításához definiálja vagy deklarálja a struct vagy union-t a globális hatókörben a függvény prototípusa előtt:

struct S;void func1( struct S * );

A /Ze alatt a tag továbbra is a globális hatókörben kerül beírásra.

Lásd még

Funkciók

.

Vélemény, hozzászólás?

Az e-mail-címet nem tesszük közzé.