2011-02-06 15 views
6

Come principiante di C, posso capire la necessità di prototipi di funzione nel file, ma non sono sicuro di un paio di cose.C funzioni prototipo

In primo luogo, ogni chiamata di funzione esterna al principale richiede una dichiarazione di prototipo? Ci sono delle condizioni in cui ciò può cambiare?

In secondo luogo, è necessario un prototipo di funzione separata per sovraccarichi di metodo?

risposta

8

Le chiamate di funzione in C non richiedono la visualizzazione di un prototipo, ma si consiglia vivamente di includere un prototipo corretto.

Il motivo è che se la definizione della funzione non corrisponde ai tipi degli argomenti della funzione dopo l'esecuzione dell'argomento della funzione predefinita, è molto probabile che si ottenga un comportamento indefinito.

Avere il prototipo corretto visibile significa che il compilatore può controllare gli argomenti di una chiamata di funzione e avvisare il programmatore in caso di mancata corrispondenza.

C non consente il sovraccarico delle funzioni, pertanto è possibile disporre di un solo prototipo per qualsiasi nome di funzione.

Le promozioni di argomento predefinito possono causare disallineamenti imprevisti.

E.g.

int main(int argc, char **argv) 
{ 
    short s = 5; 
    float f = 2.3f; 
    x(s, f);  // x implicitly declared; default argument promotions performed 
    return 0; 
} 

int x(short t, float g) // Error: called with an int and a double 
{ 
    return (int)(t + g); 
} 

nella chiamata di funzione, perché non ha x prototipo visibile (ancora), s sarà promosso a int e f sarà promosso a double. Questi sono argomento predefinito promozioni. Ciò provoca una mancata corrispondenza quando la funzione viene definita con un prototipo che prende uno short e uno float anche se questi sono i tipi originali degli argomenti che sono stati inoltrati.

Funzioni che richiedono un numero variabile di argomenti (ad es. Sintassi , ...) deve sempre avere un prototipo visibile nel punto in cui vengono chiamati.

1

No, le funzioni non sono necessarie per avere prototipi. Tuttavia, sono utili in quanto consentono di chiamare le funzioni prima che vengano dichiarate. Per esempio:

int main(int argc, char **argv) 
{ 
    function_x(); // undefined function error 
    return 0; 
} 

void function_x() 
{ 

} 

Se si aggiunge un prototipo sopra main (questo di solito è fatto in un file di intestazione) permetterebbe di chiamare function_x, anche se è definito dopo main. Questo è il motivo per cui quando si utilizza una libreria esterna che deve essere collegata, si include il file di intestazione con tutti i prototipi di funzione al suo interno.

C non ha sovraccarico di funzione, quindi non è rilevante.

+2

Il punto in cui è stato commentato non causerà un errore di compilazione. 'function_x();' implicitamente dichiarerà 'function_x();' come una funzione non prototipata che restituisce un 'int'. È un errore che la funzione viene successivamente dichiarata come 'void', tuttavia. –

0

No. In C non tutte le funzioni richiedono un prototipo. MA è una buona pratica includerlo. I prototipi aiutano il compilatore a individuare gli errori. Ovviamente alcuni compilatori C, per difetto si lamentano se mancano i prototipi prima della chiamata alla funzione, ma questo comportamento non è necessariamente uno standard.

La logica precedente si applica anche ai sovraccarichi.

Ovviamente, dato che sei nuovo di C.Penso che sia meglio andare a cercare la differenza tra un prototipo e la definizione di una funzione per dare un senso.

+0

Oops, C non ha sovraccarico! grazie a @Tim Cooper. – Outspoken

+0

È una buona disciplina di programmazione assicurarsi di trovare l'opzione del compilatore che garantisce che tutte le funzioni siano dichiarate con un prototipo completo prima di essere utilizzate, e per assicurarsi di utilizzare sempre l'opzione del compilatore e prestare attenzione ai suoi avvertimenti. –

4

Altri hanno già sottolineato che C non richiede prototipi per le funzioni. Aggiungerò solo un paio di punti minori.

Prima di tutto, senza un prototipo, gli argomenti a una funzione subiscono sempre "promozioni default" prima di essere passati come parametri, quindi (per esempio) tutti i tipi interi più piccoli vengono promossi a int e float viene promosso a double . Pertanto, senza un prototipo, è impossibile per una funzione ricevere (ad esempio) un char, short o float. Se la funzione è impostata su per ricevere uno di questi tipi, si verificherà una mancata corrispondenza tra ciò che viene passato e ciò che la funzione si aspetta, dando un comportamento indefinito (qualsiasi altra mancata corrispondenza fornisce anche un comportamento non definito).

In secondo luogo, se una funzione è definita con un elenco di argomenti variabili, allora do è necessario un prototipo, altrimenti il ​​suo richiamo determinerà un comportamento non definito.