Wenn ich es habe:
#define MAXLINE 5000
Welcher Typ ist unter MAXLINE zu verstehen? Sollte ich annehmen, dass es sich um eine int
? Kann ich das irgendwie testen?
Wie kann man im Allgemeinen die Art der #define
Variable?
Wenn ich es habe:
#define MAXLINE 5000
Welcher Typ ist unter MAXLINE zu verstehen? Sollte ich annehmen, dass es sich um eine int
? Kann ich das irgendwie testen?
Wie kann man im Allgemeinen die Art der #define
Variable?
Sie hat keinen Typ. Es handelt sich um eine einfache Textersetzung. Der Text 5000 wird an jeder Stelle, an der MAXLINE als Token auftaucht, ersetzt.
Zum Beispiel:
int a = MAXLINE;
setzt den Wert 5000 in a
.
Während
char *MAXLINE2 = "MAXLINE";
führt nicht zu
char *50002 = "5000";
Wenn Sie also eine Typprüfung wünschen, sind Makros nicht der richtige Weg. Sie werden stattdessen statische Konstanten deklarieren wollen, so dass die Typüberprüfung vom Compiler durchgeführt wird.
Für Informationen über die Unterschiede zwischen static
, const
y #define
gibt es viele Quellen, darunter auch diese Frage: Statisch, definieren und const in C
(Sehr!) Im Großen und Ganzen wird Ihr C-Compiler bei der Ausführung 3 Aufgaben erfüllen:
Führen Sie einen Vorverarbeitungsdurchlauf über Ihre Quelldateien durch,
Ausführen eines Compilers über die vorverarbeiteten Quelldateien
Führen Sie einen Linker über die resultierenden Objektdateien aus.
Zeilen, die mit einem #
, wie die Zeile
#define MAXLINE 5000
wird in der Präprozessorphase behandelt. Der Präprozessor analysiert (vereinfacht gesagt) eine Datei und führt Textersetzungen für alle Makros durch, die er entdeckt. Im Präprozessor gibt es kein Konzept von Typen.
Angenommen, Sie haben die folgenden Zeilen in Ihrer Quelldatei:
#define MAXLINE 5000
int someVariable = MAXLINE; // line 2
char someString[] = "MAXLINE"; // line 3
Der Präprozessor erkennt das Makro MAXLINE
in Zeile 2, und führt eine Textersetzung durch. Beachten Sie, dass in Zeile 3 "MAXLINE"
wird nicht als Makro behandelt, da es sich um ein Stringliteral handelt.
Nach Abschluss der Präprozessorphase sieht die Kompilierungsphase nur noch Folgendes:
int someVariable = 5000; // line 2
char someString[] = "MAXLINE"; // line 3
(Kommentare wurden der Übersichtlichkeit halber eingefügt, werden aber normalerweise vom Präprozessor entfernt) Sie können wahrscheinlich eine Option des Compilers verwenden, um die Ausgabe des Präprozessors zu überprüfen. In gcc ist die Option -E
Option wird dies tun.
Beachten Sie, dass der Präprozessor zwar kein Konzept des Typs hat, es aber keinen Grund gibt, warum Sie nicht der Vollständigkeit halber einen Typ in Ihr Makro aufnehmen können. z.B.
#define MAXLINE ((int)5000)
MAXLINE
ist überhaupt keine Variable. Tatsächlich ist es keine C-Syntax. Ein Teil des Kompilierungsprozesses führt einen Präprozessor vor dem Compiler aus, und eine der Aktionen, die der Präprozessor durchführt, ist das Ersetzen von Instanzen von MAXLINE
Token in der Quelldatei mit dem, was nach #define MAXLINE
(5000 im Code der Frage).
Nebenbei bemerkt: eine andere übliche Art, den Präprozessor in Ihrem Code zu verwenden, ist mit der #include
Richtlinie, die der Präprozessor einfach durch den vorverarbeiteten Inhalt der eingeschlossenen Datei ersetzt.
Schauen wir uns ein Beispiel für den Kompilierungsprozess in Aktion an. Hier ist eine Datei, foo.c
, die in den Beispielen verwendet werden:
#define VALUE 4
int main()
{
const int x = VALUE;
return 0;
}
Ich benutze gcc
y cpp
( den C-Präprozessor ) für die Beispiele, aber Sie können dies wahrscheinlich mit jeder Compiler-Suite tun, die Sie haben, natürlich mit anderen Flags.
Zunächst kompilieren wir foo.c
con gcc -o foo.c
. Was ist passiert? Es hat funktioniert; Sie sollten jetzt eine ausführbare Datei haben foo
.
Sie können sagen gcc
nur vorverarbeiten und keine Kompilierung vornehmen. Wenn Sie gcc -E foo.c
erhalten Sie die vorverarbeitete Datei auf der Standardausgabe. Das Ergebnis sieht folgendermaßen aus:
# 1 "foo.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "foo.c"
int main()
{
const int x = 4;
return 0;
}
Beachten Sie, dass die erste Zeile von main
hat ersetzt VALUE
con 4
.
Sie fragen sich vielleicht, was die ersten vier Zeilen bedeuten. Das sind so genannte Linemarker, und Sie können mehr über sie lesen in Ausgabe des Präprozessors .
Soweit ich weiß, können Sie die Vorverarbeitung in gcc
aber es gibt einige Ansätze, um ihm mitzuteilen, dass eine Datei bereits vorverarbeitet wurde. Selbst wenn Sie dies tun, werden die in der Datei vorhandenen Makros entfernt, da sie nicht für den Compiler bestimmt sind. Sie können sehen, womit der Compiler in dieser Situation arbeitet, indem Sie gcc -E -fpreprocessed foo.c
:
.
.
.
.
int main()
{
const int x = VALUE;
return 0;
}
Hinweis: Ich habe die Punkte oben eingefügt; tun Sie so, als ob das leere Zeilen wären (ich musste sie dort einfügen, damit diese Zeilen von SO angezeigt werden).
Diese Datei lässt sich eindeutig nicht kompilieren (versuchen Sie gcc -fpreprocessed foo.c
um das herauszufinden), denn VALUE
ist in der Quelle vorhanden, aber nirgends definiert.
Sie hat keinen Typ. Es ist nur ein Token, das der Präprozessor in den Quellcode einfügt, bevor er den Code an den Compiler weitergibt. Sie können diese (lächerliche) Sache machen, um eine Variable mit dem Namen zu deklarieren x5000
:
#define APPEND(x,y) x ## y
int main() {
int APPEND(x,5000);
x5000 = 3;
}
Der Präprozessor macht daraus das hier, bevor er es an den eigentlichen Compiler weitergibt:
int main() {
int x5000;
x5000 = 3;
}
Also, nur weil Sie sehen 5000
in einem Makro ist, bedeutet das nicht, dass es in irgendeiner Weise numerisch sein muss.
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.