Funktionsprototyper

  • 11/04/2016
  • 3 minuter att läsa
    • c
    • v
    • n
    • M
    • g
    • +1

En funktionsdeklaration föregår funktionsdefinitionen och anger namnet, returtyp, lagringsklass och andra attribut för en funktion. För att vara en prototyp måste funktionsdeklarationen också fastställa typer och identifierare för funktionens argument.

Syntax

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

/* attribute-seqopt är Microsoft-specifik */

declaration-specifiers:
lagringsklass-specifier deklaration-specifiersopt
typ-specifier deklaration-specifiersopt
typ-qualifier deklaration-specifiersopt

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

init-declarator:
declarator
declarator = initializer

declarator:
pointeropt direct-declarator

direct-declarator: /* En funktionsdeklarator */
direct-declarator ( parameter-type-list ) /* Deklarator i ny stil */
direct-declarator ( identifier-listopt ) /* Deklarator i föråldrad stil */

Prototypen har samma form som funktionsdefinitionen, med undantag för att den avslutas med ett semikolon omedelbart efter den avslutande parentesen och har därför ingen kropp. I båda fallen måste returtypen överensstämma med den returtyp som anges i funktionsdefinitionen.

Funktionsprototyper har följande viktiga användningsområden:

  • De fastställer returtypen för funktioner som returnerar andra typer än int. Även om funktioner som returnerar int-värden inte kräver prototyper rekommenderas prototyper.

  • Om inte fullständiga prototyper görs standardkonverteringar, men inget försök görs att kontrollera typen eller antalet argument med antalet parametrar.

  • Prototyper används för att initialisera pekare till funktioner innan dessa funktioner är definierade.

  • Parameterlistan används för att kontrollera överensstämmelsen mellan argumenten i funktionsanropet och parametrarna i funktionsdefinitionen.

Den konverterade typen av varje parameter bestämmer tolkningen av de argument som funktionsanropet placerar på stacken. En typmissmatchning mellan ett argument och en parameter kan leda till att argumenten på stacken misstolkas. Om till exempel en 16-bitars dator har en 16-bitars pekare som argument och sedan deklareras som en long-parameter, tolkas de första 32 bitarna på stapeln som en long-parameter. Detta fel skapar problem inte bara med long-parametern utan med alla parametrar som följer efter den. Du kan upptäcka fel av det här slaget genom att deklarera fullständiga funktionsprototyper för alla funktioner.

En prototyp fastställer attributen för en funktion så att anrop till funktionen som föregår dess definition (eller förekommer i andra källfiler) kan kontrolleras för felmatchning av argument- och returtyp. Om du till exempel anger specifikationen static storage-class i en prototyp måste du också ange static storage-class i funktionsdefinitionen.

Fullständiga parameterdeklarationer (int a) kan blandas med abstrakta deklaratorer (int) i samma deklaration. Följande deklaration är till exempel laglig:

int add( int a, int );

Prototypen kan innehålla både typen av och en identifierare för varje uttryck som skickas som argument. Sådana identifierare har dock endast räckvidd fram till slutet av deklarationen. Prototypen kan också återspegla det faktum att antalet argument är variabelt, eller att inga argument lämnas över. Utan en sådan lista kan det hända att felmatchningar inte avslöjas, så kompilatorn kan inte generera diagnostiska meddelanden om dem. Se Argumenten för mer information om typkontroll.

Prototype scope i Microsoft C-kompilatorn är nu ANSI-kompatibel när man kompilerar med kompilatoralternativet /Za. Detta innebär att om du deklarerar en struct– eller union-tagg inom en prototyp, skrivs taggen in i detta scope snarare än i det globala scope. När du kompilerar med /Za för ANSI-överensstämmelse kan du till exempel aldrig anropa den här funktionen utan att få ett typfel:

void func1( struct S * );

För att korrigera koden definierar eller deklarerar du struct eller union i global räckvidd före funktionsprototypen:

struct S;void func1( struct S * );

Med /Ze skrivs taggen fortfarande in i global räckvidd.

Visa även

Funktioner

Lämna ett svar

Din e-postadress kommer inte publiceras.