Wenn ich habe:
#define MAXLINE 5000
Welcher Typ ist unter MAXLINE zu verstehen? Sollte ich davon ausgehen, dass es sich um eine int
? Kann ich das irgendwie testen?
Wie kann man im Allgemeinen die Art von bestimmen #define
ed-Variable?
James Raizew
Wenn ich habe:
#define MAXLINE 5000
Welcher Typ ist unter MAXLINE zu verstehen? Sollte ich davon ausgehen, dass es sich um eine int
? Kann ich das irgendwie testen?
Wie kann man im Allgemeinen die Art von bestimmen #define
ed-Variable?
tpg2114
Es hat keinen Typ. Es ist eine einfache Textersetzung. Der Text 5000 wird dort abgelegt, wo MAXLINE als Token erscheint.
Zum Beispiel:
int a = MAXLINE;
wird den Wert 5000 eingeben a
.
Während
char *MAXLINE2 = "MAXLINE";
wird nicht dazu führen
char *50002 = "5000";
Wenn Sie also eine Typprüfung wünschen, sind Makros nicht der richtige Weg. Sie sollten stattdessen statische Konstanten deklarieren, damit die Typprüfung vom Compiler durchgeführt wird.
Informationen zu den Unterschieden zwischen static
, const
und #define
gibt es viele Quellen, einschließlich dieser Frage: Static, define und const in C
bei arithmetischen Operationen, in welchen Datentyp #define Konstanten hochgestuft werden (ich meinte implizite Konvertierung). Wenn sie größer als der Integer-Typ sind, wird am Ende mit dem Suffix L oder LL abgeschnitten? Wenn ich Float (#define FLT_VAR 3.0) verwende, wird dies als Float oder Double behandelt?
– Rajesh
21. September 2021 um 1:30 Uhr
Andrew Edgecombe
(Sehr!) Im Großen und Ganzen wird Ihr C-Compiler 3 Aufgaben ausführen, wenn er ausgeführt wird:
Führen Sie einen Vorverarbeitungsdurchlauf über Ihre Quelldateien aus,
Führen Sie einen Compiler über die vorverarbeiteten Quelldateien aus
Führen Sie einen Linker über die resultierenden Objektdateien aus.
Zeilen beginnend mit a #
wie die Linie
#define MAXLINE 5000
wird von der Präprozessorphase behandelt. (vereinfacht) Der Präprozessor analysiert eine Datei und führt Textersetzungen für alle Makros durch, die er erkennt. Innerhalb des Präprozessors gibt es kein Typenkonzept.
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 Textsubstitution durch. Beachten Sie, dass in Zeile 3 "MAXLINE"
wird nicht als Makro behandelt, da es sich um ein Zeichenfolgenliteral handelt.
Nach Abschluss der Präprozessorphase wird in der Kompilierungsphase nur Folgendes angezeigt:
int someVariable = 5000; // line 2
char someString[] = "MAXLINE"; // line 3
(Kommentare wurden aus Gründen der Übersichtlichkeit hinterlassen, werden aber normalerweise vom Präprozessor entfernt) Sie können wahrscheinlich eine Option im Compiler verwenden, um die Ausgabe des Präprozessors überprüfen zu können. Im gcc die -E
Option wird dies tun.
Beachten Sie, dass der Präprozessor zwar kein Typkonzept hat, es aber keinen Grund gibt, der Vollständigkeit halber keinen Typ in Ihr Makro aufzunehmen. z.B
#define MAXLINE ((int)5000)
Der Compiler sieht diese Codezeile nie, ein Präprozessor läuft vor der eigentlichen Kompilierung und ersetzt diese Makros durch ihre Literalwerte, siehe Link unten für weitere Informationen
Es 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 tun, um eine Variable namens zu deklarieren x5000
:
#define APPEND(x,y) x ## y
int main() {
int APPEND(x,5000);
x5000 = 3;
}
Der Präprozessor verwandelt das in Folgendes, bevor er es dem eigentlichen Compiler übergibt:
int main() {
int x5000;
x5000 = 3;
}
Also, nur weil du es siehst 5000
In einem Makro bedeutet dies nicht, dass es in irgendeiner Weise numerisch sein muss.
David Alber
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 ausführt, besteht darin, Instanzen von zu ersetzen MAXLINE
Tokens in der Quelldatei mit allem, was danach kommt #define MAXLINE
(5000 im Code der Frage).
Abgesehen davon: Eine andere übliche Art, wie Sie den Präprozessor in Ihrem Code verwenden, ist mit dem #include
Direktive, die der Präprozessor einfach durch den vorverarbeiteten Inhalt der eingebundenen Datei ersetzt.
Sehen 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
und cpp
(der C-Präprozessor) für die Beispiele, aber Sie können dies wahrscheinlich mit jeder beliebigen Compiler-Suite tun, natürlich mit unterschiedlichen Flags.
Lassen Sie uns zuerst kompilieren foo.c
mit gcc -o foo.c
. Was ist passiert? Es funktionierte; Sie sollten jetzt eine ausführbare Datei haben foo
.
Du kannst sagen gcc
nur vorverarbeiten und keine Kompilierung durchführen. Wenn Sie tun gcc -E foo.c
, erhalten Sie die vorverarbeitete Datei auf Standardausgabe. Hier ist, was es produziert:
# 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
mit 4
.
Sie fragen sich vielleicht, was die ersten vier Zeilen sind. Diese werden Linienmarkierungen genannt, und Sie können mehr darüber in lesen Ausgabe des Präprozessors.
Soweit ich weiß, können Sie die Vorverarbeitung nicht vollständig überspringen gcc
, aber es gibt ein paar Ansätze, um ihm mitzuteilen, dass eine Datei bereits vorverarbeitet wurde. Selbst wenn Sie dies tun, werden jedoch in der Datei vorhandene Makros entfernt, da sie nicht für den Compilerverbrauch bestimmt sind. Sie können sehen, womit der Compiler in dieser Situation arbeitet gcc -E -fpreprocessed foo.c
:
.
.
.
.
int main()
{
const int x = VALUE;
return 0;
}
Hinweis: Ich habe die Punkte oben eingefügt; so tun, als wären das leere Zeilen (ich musste sie dort einfügen, damit diese Zeilen von SO angezeigt werden).
Diese Datei wird eindeutig nicht kompiliert (versuchen Sie es gcc -fpreprocessed foo.c
herauszufinden) weil VALUE
ist in der Quelle vorhanden, aber nirgendwo definiert.
Shinku
Wir nennen dieses Makro oder Präprozessor, das verwendet wird, um den Inhalt der Quelldatei durch Zeichenfolgen zu ersetzen. Lesen Sie dies: https://en.wikipedia.org/wiki/C_macro
Edgar Bonnet
Ja, davon kann man ausgehen int
.
Nun, eigentlich sind alle anderen Antworten richtig. Es ist nicht C, es ist nur eine Direktive, die den Präprozessor anweist, einige Textersetzungen vorzunehmen, und als solche hat es keinen Typ. Wenn Sie jedoch keine verrückten Dinge damit machen (wie den ##-Präprozessor-Trick), werden Sie normalerweise verwenden MAXLINE
wie eine Art Konstante, und der Präprozessor ersetzt sie durch 5000
was tatsächlich eine explizite Konstante ist. Und Konstanten haben Typ: 5000
ist ein int
. Eine als Dezimalzahl geschriebene Konstante ohne Suffix (wie U oder L) wird vom Compiler als interpretiert int
, long int
oder unsigned long int
: der erste dieser Typen, der passt.
Aber das hat natürlich nichts mit dem Vorgänger zu tun. Sie könnten Ihre Frage umformulieren in „Was ist die Art von 5000
?”, ohne
#define
.