Nel caso in cui disponga di una variabile che può essere utilizzata in diverse fonti, è buona norma dichiararla in un'intestazione? o è meglio dichiararlo in un file .c
e utilizzare extern
in altri file?Dichiarazione di variabili in un file di intestazione
risposta
Si dovrebbe dichiarare la variabile in un file di intestazione:
extern int x;
e quindi definire in uno file C:
int x;
In C, la differenza tra una definizione e una dichiarazione è che la definizione riserva spazio per la variabile, mentre la dichiarazione introduce semplicemente la variabile nella tabella dei simboli per collegare il tempo).
È possibile (dovrebbe) dichiararlo come extern
in un file di intestazione e definirlo esattamente nel file 1 .c.
Si noti che il file .c dovrebbe anche usare l'intestazione e che il modello standard si presenta come:
// file.h
extern int x; // declaration
// file.c
#include "file.h"
int x = 1; // definition and re-declaration
Infatti * dovrebbe * usare sempre l'intestazione, in modo che se i tipi escono da whack tra la dichiarazione e la definizione il compilatore te lo dirà. – caf
cat, hai ragione, lo ridiscuterò un po '. –
Se si dichiara come
int x;
in un file di intestazione che viene poi inclusa in più luoghi, ci si ritroverà con più istanze di x (e potenzialmente compilare o problemi di collegamento).
Il modo corretto per avvicinarsi a questo è quello di avere il file di intestazione dire
extern int x; /* declared in foo.c */
e poi in foo.c si può dire
int x; /* exported in foo.h */
quindi è possibile includere il file di intestazione in ben luoghi come ti piace
La chiave è di mantenere invariate le dichiarazioni della variabile nel file di intestazione e nel file di origine.
Io uso questo trucco
------sample.c------
#define sample_c
#include sample.h
(rest of sample .c)
------sample.h------
#ifdef sample_c
#define EXTERN
#else
#define EXTERN extern
#endif
EXTERN int x;
Sample.c viene compilata una sola volta e che definisce le variabili. Qualsiasi file che include sample.h viene assegnato solo "extern" della variabile; assegna lo spazio per quella variabile.
Quando si modifica il tipo di x, cambierà per tutti. Non dovrai ricordarti di cambiarlo nel file sorgente e nel file di intestazione.
Come gestite l'inizializzazione? - extern int x = 6; darebbe un avvertimento alla maggior parte dei compilatori. – Dipstick
@chrisharris: questa è una limitazione. Di solito ho un Init() in ogni modulo per inizializzare le variabili. – Robert
Non ti sembra meno ingombrante avere la dichiarazione extern nell'intestazione e la definizione nel file C? Come @caf ha commentato, se i tipi non corrispondono si ottiene un avviso (io comunque includo sempre il file di intestazione nel file c corrispondente, dal momento che ho bisogno che tutte le funzioni abbiano un prototipo). – Gauthier
E questa soluzione?
#ifndef VERSION_H
#define VERSION_H
static const char SVER[] = "14.2.1";
static const char AVER[] = "1.1.0.0";
#else
extern static const char SVER[];
extern static const char AVER[];
#endif /*VERSION_H */
L'unico limite che vedo è che la guardia includere non ti salva se si include due volte nello stesso file.
1) La protezione #ifndef impedisce più definizioni in un file sorgente * single * (quindi le definizioni esterne non fanno nulla). 2) Dichiarare una variabile statica in un'intestazione significa che ogni file sorgente che lo include avrà la sua versione di quella variabile piuttosto che una singola variabile condivisa. Tecnicamente questo collegherà, ma il comportamento potrebbe non essere desiderato (potrebbe non notare come hai usato le variabili const in questo esempio, ma usalo per qualcosa di non-const e vedrai che conta). La risposta accettata è quasi sempre la soluzione appropriata. – Assimilater
- 1. Dichiarazione di oggetti classe in un file di intestazione
- 2. Dichiarazione di vettori in un file di intestazione C++
- 3. Dichiarazione di variabili all'interno di un loop
- 4. Dichiarazione di variabili globali in Swift
- 5. Dichiarazione di intestazione e file di intestazione C++ che termina con "= 0"
- 6. dichiarazione di variabili nelle @implementation
- 7. Dichiarazione di variabili senza valore
- 8. Dichiarazione di variabili membro private
- 9. Dichiarazione di variabili in celle Excel
- 10. Dichiarazione di variabili punto di domanda
- 11. Come assegnare ad un elenco di variabili in una dichiarazione
- 12. Dichiarazione di variabili di istanza che iterano su un hash!
- 13. YouCompleteMe, file di intestazione
- 14. Dichiarazione di variabili e scope per Lua
- 15. MYSQL dichiarazione delle variabili
- 16. Ri-dichiarazione di variabili all'interno di loop in Java
- 17. `static`,` extern`, `const` nel file di intestazione
- 18. dichiarazione di variabili globali nel progetto iPhone
- 19. Dichiarazione di variabili senza nome - perché funziona?
- 20. Modifica file di intestazione IDL generato
- 21. Definizione di variabile nei file di intestazione
- 22. Javascript - Assegnazione di più variabili di opporsi proprietà utilizzando parentesi graffe in dichiarazione di variabili
- 23. dichiarazione anticipata di variabili/classi di namespace std
- 24. Perché l'implementazione e la dichiarazione di una classe template devono essere nello stesso file di intestazione?
- 25. Intestazione per file sorgente
- 26. Valutare più variabili in una dichiarazione "se"?
- 27. dichiarazione di variabili semplici nelle viste in Laravel
- 28. Utilizzando la lettera L in lunga dichiarazione di variabili
- 29. Dichiarazione di funzione C
- 30. Dichiarazione e impostazione di variabili in un'istruzione Select
** Entrambi ** sono dichiarazioni! Nell'ambito del file, il secondo non è una definizione (completa), ma una definizione _tentativa_. – Olaf