Art der #define-Variablen

Lesezeit: 6 Minuten

Benutzeravatar von James Raitsev
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 #defineed-Variable?

Benutzeravatar von tpg2114
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, constund #definegibt 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

Benutzeravatar von Andrew Edgecombe
Andrew Edgecombe

(Sehr!) Im Großen und Ganzen wird Ihr C-Compiler 3 Aufgaben ausführen, wenn er ausgeführt wird:

  1. Führen Sie einen Vorverarbeitungsdurchlauf über Ihre Quelldateien aus,

  2. Führen Sie einen Compiler über die vorverarbeiteten Quelldateien aus

  3. 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

http://www.cplusplus.com/doc/tutorial/preprocessor/

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.

Benutzeravatar von David Alber
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.

Beispiel

Sehen wir uns ein Beispiel für den Kompilierungsprozess in Aktion an. Hier ist eine Datei, foo.cdie 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.

Zusammenstellung

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.

Nur Vorverarbeitung

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.

Zusammenstellung ohne Vorverarbeitung

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.

Benutzeravatar von shinkou
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

Benutzeravatar von Edgar Bonet
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.

1411090cookie-checkArt der #define-Variablen

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy