2017-01-31 3 views
4

Ich fange gerade an, C zu lernen, also ist dies hoffentlich keine dumme Frage. Das Problem, das ich habe, betrifft Header-Dateien und #define für Konstanten verwenden. Ich habe gelesen, dass ich das Folgende verwenden sollte, um zu verhindern, dass mein Header mehr als einmal kompiliert wird.Verwendung in einer c-Header-Datei definieren

#ifndef NAME_OF_FILE 
#define NAME_OF_FILE 
. 
. //my header file content 
. 
#endif 

Ich möchte eine Konstante hinzuzufügen, und ich glaube, ich auch eine #define wie

#ifndef NAME_OF_FILE 
#define NAME_OF_FILE 

#define NUM_CONST 5 //the constant I want in my header file 
. 
. 
. 
#endif 

Wie kennt C# define, dass NAME_OF_FILE bezieht sich auf die H-Datei während verwenden würde #define NUM_CONST 5 ist nur eine Konstante? Liegt es am Wert von NUM_CONST? Oder habe ich das alles komplett falsch?

+1

Der Compiler weiß _not_ nicht, dass 'NAME_OF_FILE' speziell ist. Es ist nur speziell von _convention_. Es ist die "Sperre" für die Datei (dh die Datei könnte mehrfach eingeschlossen sein, aber die Sperre verhindert, dass der Inhalt zwischen dem Sperrkonstrukt und dem entsprechenden "# endif" vom Compiler mehr als einmal gelesen wird . Es ist der C-Präprozessor, der dies tatsächlich tut. Wenn Sie der Logik Schritt für Schritt folgen, ist das "# ifndef" das erste Mal wahr, also ist die [1st] '# define' und der Rest enthalten. Bei dem zweiten Versuch ist das '# ifndef' falsch und springt zu dem' # endif' am unteren Ende. –

Antwort

3

#define IDENTIFIER definiert die Kennung für den sakes von #ifdef, aber was es zu definiert wird, ist die leere Zeichenfolge.

So

#define NAME_OF_FILE 

int main() 
{ 
    int x = NAME_OF_FILE; 
} 

würde lösen zu

int main() 
{ 
    int x = ; 
} 

So gibt kein "Wissen" beteiligt ist, nur eine definierte, aber leer.

(Aus diesem Grunde einig Stilen da draußen führt #define NAME_OF_FILE NAME_OF_FILE empfehlen, so dass, wenn NAME_OF_FILE geschieht in der Quelle verwendet werden, es ersetzt-mit-Selbst wird vom Präprozessor.)

+0

Eine gute Idee über '#define NAME_OF_FILE NAME_OF_FILE'! Ich habe nie davon gehört; Hast du einen Link zu dem, wo es erwähnt wird? – anatolyg

+0

@anatolyg: Es war eine * loooong * Zeit (versuche 15 Jahre oder so), da ich mich mit Style Guides beschäftigt habe. Die wichtigen Dinge werden zur zweiten Natur, die rein stilistischen, die du mit Werkzeugen wie Astyle behandelst. Es war herum, und ich nahm es als "es kann nicht weh tun, also warum nicht." Keine Ahnung, woher ich es habe. – DevSolar

4

Es gibt keine wesentliche Unterschied zwischen den beiden definiert. #define NAME_OF_FILE und #define NUM_CONST 5 sind die gleiche Art von Sache. Sie definieren einen Klartextaustausch von Tokens (im ersten Fall ist der Ersatz nichts).

Zum Beispiel könnten Sie nachfolgenden Code setzen:

printf("%d\n", NAME_OF_FILE NUM_CONST NAME_OF_FILE); 

und nach den obigen Substitutionen der Code würde sich um:

printf("%d\n", 5); 

was richtig ist. Es gibt keine "Magie". Der Kompilierungsschritt, der diese Substitutionen ausführt, wird gewöhnlich als "Vorverarbeitung" bezeichnet.

NAME_OF_FILE bezieht sich nicht auf die .h Datei per se, aber die Verwendung der ifndef Direktive erreicht das Ziel, den gleichen Code nicht zweimal zu kompilieren.

4

Es tut es nicht. NAME_OF_FILE könnte alles sein. Sie könnten haben

#ifndef PRETTY_PINK_PRINCESS 
#define PRETTY_PINK_PRINCESS 
/* definitions */ 
#endif 

Und es würde genauso gut funktionieren. Die Verwendung von NAME_OF_FILE ist nur eine Konvention, weil es wahrscheinlich ist, dass es einzigartig ist.

0

Für die Compiler beide dieser Aussage vom gleichen Typ ist ein Makro

#define NAME_OF_FILE 

#define NUM_CONST 5 

Dass diese

konstruieren
#ifndef NAME_OF_FILE 
#define NAME_OF_FILE 
. 
. //my header file content 
. 
#endif 

tun, ist, dass der Header zum ersten Mal verarbeitet wird, die marco " NAME_OF_FILE "ist nicht definiert, daher wird es definiert und der gesamte Inhalt der Header-Datei verarbeitet. Beim zweiten Mal kommt der Compiler dazu, weil der Header mehr als einmal im Projekt enthalten war, dass der Marco jetzt definiert ist und die Headerdatei nicht erneut verarbeitet wird. Erneut ist dem "c-code" nicht bewusst, dass der marco __TEST_H zum Beispiel seinen Namen hat, weil der Name der Header-Datei 'test.h' ist. Sie meinen wahrscheinlich, dass Ihre IDE automatisch den marco generiert hat, dann haben Sie die Header-Datei erstellt und die IDE hat den marco nach der Datei für die Bequemlichkeit des Benutzers aufgerufen. Wie schon ein anderer hier gesagt, dass du den marco umbenennen kannst (benenne ihn im ganzen Projekt um, ich meine damit) und der Code würde sich kompilieren und generell genauso verhalten wie zuvor.

Verwandte Themen