Domanda

Speriamo che questo sia una domanda molto semplice. Segue il C pgm (test.c) ho.

#include <stdio.h>
//#include <stdlib.h>

int main (int argc, char *argv[]) {
    int intValue = atoi("1");
    double doubleValue = atof("2");
    fprintf(stdout,"The intValue is %d and the doubleValue is %g\n", intValue, doubleValue);
    return 0;
}

Si noti che sto usando atoi () e atof () da stdlib.h, ma non includono tali file di intestazione. Compilo il pgm (gcc test.c) ed ottengo nessun errore del compilatore!

I eseguire il pgm (./a.out) e qui è l'uscita, che è sbagliato.

The intValue is 1 and the doubleValue is 0

Ora includono stdlib.h (rimuovendo i commenti prima del #include) e ricompilare ed eseguirlo di nuovo. Questa volta ho l'uscita a destra:

The intValue is 1 and the doubleValue is 2

Come mai il compilatore non si lamentava, non compreso lo stdlib.h e ancora mi ha lasciato usare l'atoi (), atof () funzioni?

Le mie info gcc:

$ gcc --version
gcc (GCC) 4.1.2 20070925 (Red Hat 4.1.2-27)

Ogni pensiero apprezzato!

È stato utile?

Soluzione

Per ragioni storiche - in particolare, la compatibilità con molto i vecchi programmi C (pre-C89) - utilizzando una funzione senza aver dichiarato provoca dapprima solo un avviso da GCC, non un errore. Ma il tipo di ritorno di tale funzione un si presume essere int, non double, motivo per cui viene eseguito il programma in modo non corretto.

Se si utilizza -Wall sulla riga di comando, si ottiene una diagnosi:

$ gcc -Wall test.c
test.c: In function ‘main’:
test.c:5: warning: implicit declaration of function ‘atoi’
test.c:6: warning: implicit declaration of function ‘atof’

Si dovrebbe usare -Wall praticamente sempre. Altre opzioni di avviso molto utili per il nuovo codice sono -Wextra, -Wstrict-prototypes, -Wmissing-prototypes, -pedantic, e -Wwrite-strings, ma rispetto a -Wall hanno molto più alti tassi positivi falsi.

tangenziali: non usare mai né atoi atof, si nascondono gli errori di input. Usa strtol e strtod invece.

Altri suggerimenti

Se non si specifica altrimenti, credo che un compilatore C sarà solo intuire che le funzioni non dichiarate prendono la forma extern int foo(). Quale è il motivo per atoi funziona e atof non lo fa. Quali bandiere compilatore era in uso? Propongo di usare -Wall per accendere un mucchio di avvertimenti gcc, che dovrebbe includere riferimenti funzioni non dichiarate.

C consente di chiamare una funzione senza avere una dichiarazione per quella funzione.

La funzione viene assunta per restituire un int e gli argomenti saranno trasmesse utilizzando le promozioni di default. Se quelli non corrispondono in realtà si aspetta la funzione, si otterrà un comportamento indefinito.

compilatori spesso avvertire di questo caso, ma non sempre (e che dipenderà anche dalla configurazione compilatore).

In C, quando si utilizza una funzione che non è stato dichiarato, si presume che esso ha il prototipo di default:

int FUNCTION_NAME();

Si noti che in C usando () come mezzo di prototipo accetta alcun argomento.

Se si compila con il flag -Wall (vi consiglio di usare sempre questo flag, in quanto permette a tutte le avvertenze consigliate) si otterrà un messaggio di avviso (non un errore) che ti dice che si sta utilizzando una funzione non dichiarata.

C, purtroppo, non richiede funzioni che devono essere la creazione del prototipo (o addirittura dichiarati) prima dell'uso - ma senza un prototipo, rende automaticamente alcune ipotesi circa la funzione. Uno di questi è che restituisca un int. Nel tuo caso, atoi fa restituire un int, quindi funziona correttamente. atof non lo fa, in modo che non funziona correttamente. In mancanza di un prototipo / dichiarazione, si ottiene un comportamento non definito - di solito si finirà per il recupero qualsiasi valore sembra essere nel registro dove un int normalmente essere restituito, e utilizzando tale. Sembra che nel tuo caso particolare, che sembra essere uno zero, ma potrebbe benissimo essere qualcosa d'altro.

Questo è uno dei motivi per cui molte persone spingono "C ++ come una migliore C" - C ++ richiede che tutte le funzioni siano dichiarate prima dell'uso, e, inoltre, che si specificano i tipi di tutti i parametri (non variadic) nonché ( cioè dichiarazione di funzione un C ++ è come un prototipo C, non come una dichiarazione C).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top