- 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 aint
é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
.