Prototipuri de funcții

  • 11/04/2016
  • 3 minute de citit
    • c
    • v
    • n
    • M
    • g
    • +1

O declarație de funcție precede definiția funcției și specifică numele, tipul de retur, clasa de stocare și alte atribute ale unei funcții. Pentru a fi un prototip, declarația funcției trebuie să stabilească, de asemenea, tipurile și identificatorii pentru argumentele funcției.

Sintaxa

declarație:
declaration-specifiers attribute-seqopt init-declarator-listopt ;

/* attribute-seqopt este specific Microsoft */

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
declarator = initializer

declarator:
pointeropt direct-declarator

direct-declarator: /* Un declarator de funcție */
direct-declarator ( parameter-type-list ) /* Declarator în stil nou */
direct-declarator ( identifier-listopt ) /* Declarator în stil învechit */

Prototipul are aceeași formă ca și definiția funcției, cu excepția faptului că se termină cu un punct și virgulă imediat după paranteza de închidere și, prin urmare, nu are corp. În ambele cazuri, tipul de retur trebuie să fie în concordanță cu tipul de retur specificat în definiția funcției.

Prototipurile de funcții au următoarele utilizări importante:

  • Ele stabilesc tipul de retur pentru funcțiile care returnează alte tipuri decât int. Deși funcțiile care returnează valori int nu necesită prototipuri, prototipurile sunt recomandate.

  • Fără prototipuri complete, se fac conversii standard, dar nu se încearcă să se verifice tipul sau numărul de argumente cu numărul de parametri.

  • Prototipurile sunt folosite pentru a inițializa pointeri la funcții înainte ca aceste funcții să fie definite.

  • Lista de parametri este utilizată pentru a verifica corespondența argumentelor din apelul de funcție cu parametrii din definiția funcției.

Tipul convertit al fiecărui parametru determină interpretarea argumentelor pe care apelul de funcție le plasează pe stivă. O neconcordanță de tip între un argument și un parametru poate face ca argumentele de pe stivă să fie interpretate greșit. De exemplu, pe un calculator pe 16 biți, dacă un pointer pe 16 biți este trecut ca argument, apoi declarat ca parametru long, primii 32 de biți de pe stivă sunt interpretați ca un parametru long. Această eroare creează probleme nu numai cu parametrul long, ci și cu toți parametrii care îl urmează. Puteți detecta erorile de acest tip declarând prototipuri complete ale funcțiilor pentru toate funcțiile.

Un prototip stabilește atributele unei funcții, astfel încât apelurile la funcția care preced definiția sa (sau care apar în alte fișiere sursă) pot fi verificate pentru neconcordanțe între tipul de argument și tipul de retur. De exemplu, dacă specificați specificatorul de clasă de stocare static într-un prototip, trebuie să specificați, de asemenea, clasa de stocare static în definiția funcției.

Declarațiile de parametri compleți (int a) pot fi amestecate cu declaratori abstracți (int) în aceeași declarație. De exemplu, următoarea declarație este legală:

int add( int a, int );

Prototipul poate include atât tipul, cât și un identificator pentru fiecare expresie care este transmisă ca argument. Cu toate acestea, astfel de identificatori au domeniu de aplicare numai până la sfârșitul declarației. Prototipul poate reflecta, de asemenea, faptul că numărul de argumente este variabil sau că nu se transmite niciun argument. Fără o astfel de listă, este posibil ca neconcordanțele să nu fie dezvăluite, astfel încât compilatorul nu poate genera mesaje de diagnosticare referitoare la acestea. Consultați Arguments pentru mai multe informații despre verificarea tipurilor.

Scopul prototipului în compilatorul Microsoft C este acum conform cu ANSI atunci când se compilează cu opțiunea de compilare /Za. Acest lucru înseamnă că, dacă declarați o etichetă struct sau union în cadrul unui prototip, eticheta este introdusă în domeniul respectiv și nu în domeniul global. De exemplu, atunci când se compilează cu /Za pentru conformitate ANSI, nu veți putea niciodată să apelați această funcție fără a obține o eroare de necorespundere de tip:

void func1( struct S * );

Pentru a vă corecta codul, definiți sau declarați struct sau union în domeniul global înainte de prototipul funcției:

struct S;void func1( struct S * );

Cu /Ze, eticheta este introdusă în continuare în domeniul global.

Vezi și

Funcții

.

Lasă un răspuns

Adresa ta de email nu va fi publicată.