- 11/04/2016
- 3 minuuttia aikaa
-
- c
- v
- n
- M
- g
-
+1
Funktion julistus edeltää funktion määritelmää ja määrittää nimen, paluutyypin, tallennusluokan ja muut funktion ominaisuudet. Ollakseen prototyyppi funktion julistuksen on myös määritettävä tyypit ja tunnisteet funktion argumenteille.
Syntax
declaration:
declaration-specifiers attribute-seqopt init-declarator-listopt ;
/* attribute-seqopt on Microsoft-kohtainen */
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: */
direct-declarator ( parameter-type-list ) /* Uuden tyylinen deklaraattori */
direct-declarator ( identifier-listopt ) /* Vanhentuneen tyylinen deklaraattori */
Prototyyppi on muodoltaan samanlainen kuin funktiomääritelmä, paitsi että se lopetetaan puolipisteellä heti sulkeutuvan sulkeutumissäännöksen perässä eikä sillä siten ole runkoa. Kummassakin tapauksessa paluutyypin on oltava sama kuin funktiomääritelmässä määritetty paluutyyppi.
Funktion prototyypeillä on seuraavat tärkeät käyttötarkoitukset:
-
Ne määrittelevät paluutyypin funktioille, jotka palauttavat muita tyyppejä kuin
int
. Vaikka funktiot, jotka palauttavatint
-arvoja, eivät vaadi prototyyppejä, prototyyppejä suositellaan. -
Ei täydellisiä prototyyppejä käytetä, standardimuunnokset tehdään, mutta argumenttien tyyppiä tai lukumäärää ei yritetä tarkistaa parametrien lukumäärällä.
-
Prototyyppejä käytetään funktioiden osoittimien alustamiseen, ennen kuin funktiot on määritelty.
-
Parametriluettelon avulla tarkistetaan funktiokutsussa olevien argumenttien vastaavuus funktiomäärittelyssä olevien parametrien kanssa.
Kunkin parametrin muunnettu tyyppi määrittää argumenttien tulkinnan, jonka funktiokutsu sijoittaa pinoon. Argumentin ja parametrin välinen tyyppivirhe voi aiheuttaa sen, että pinossa olevat argumentit tulkitaan väärin. Jos esimerkiksi 16-bittisessä tietokoneessa 16-bittinen osoitin välitetään argumenttina ja ilmoitetaan sitten long
-parametriksi, pinon ensimmäiset 32 bittiä tulkitaan long
-parametriksi. Tämä virhe aiheuttaa ongelmia paitsi long
-parametrin myös kaikkien sitä seuraavien parametrien kanssa. Voit havaita tämänkaltaiset virheet ilmoittamalla kaikille funktioille täydelliset funktioiden prototyypit.
Prototyyppi määrittää funktion ominaisuudet, jotta sen määrittelyä edeltävät (tai muissa lähdetiedostoissa esiintyvät) kutsut funktiolle voidaan tarkistaa argumenttityyppi- ja paluutyyppivirheiden varalta. Jos esimerkiksi prototyypissä määritetään static
-varastointiluokan määrittäjä, myös funktion määritelmässä on määritettävä static
-varastointiluokka.
Täydelliset parametri-ilmoitukset (int a
) voidaan sekoittaa abstraktien ilmoittajien (int
) kanssa samassa ilmoituksessa. Esimerkiksi seuraava deklaraatio on laillinen:
int add( int a, int );
Prototyyppi voi sisältää sekä tyypin että tunnisteen jokaiselle lausekkeelle, joka välitetään argumenttina. Tällaisilla tunnisteilla on kuitenkin soveltamisalaa vain julistuksen loppuun asti. Prototyyppi voi myös heijastaa sitä, että argumenttien lukumäärä on muuttuva tai että argumentteja ei välitetä. Ilman tällaista luetteloa yhteensopimattomuudet eivät välttämättä paljastu, joten kääntäjä ei voi tuottaa niitä koskevia diagnoosiviestejä. Katso lisätietoja tyypintarkistuksesta kohdasta Argumentit.
Prototyypin laajuus Microsoft C-kääntäjässä on nyt ANSI-yhteensopiva, kun käännetään /Za-kääntäjäoptiolla. Tämä tarkoittaa, että jos julistat struct
– tai union
-tunnisteen prototyypin sisällä, tunniste syötetään kyseisessä laajuudessa eikä globaalissa laajuudessa. Kun esimerkiksi käännetään /Za:lla ANSI-yhteensopivuutta varten, et voi koskaan kutsua tätä funktiota saamatta tyyppivirheitä:
void func1( struct S * );
Koodin korjaamiseksi määrittele tai ilmoita struct
tai union
globaalissa laajuudessa ennen funktion prototyyppiä:
struct S;void func1( struct S * );
Käytettäessä komentoa /Ze tunniste syötetään edelleen globaalissa laajuudessa.
Katsokaa myös
Funktiot