Zum Inhalt springen

#define - Anwendung?


DITTY

Empfohlene Beiträge

Sers COM,

Ich habe eine Frage bzgl. der Präprozessor-Direktive #define:

Syntax:

#define bezeichner ersatzliste

#define bezeichner(bezeichner_liste) ersatzliste

Link: C/C++ - Direktive #define

Ich weis, dass der erstere Fall dazu gedacht ist, sowas, wie Konstanten zuschaffen (zumindest bei C) bzw. eigene Schlüsselwärter zu definieren.

1.)

Wurden auch so die Schlüsselwörter int, float, bool, etc. definiert und zur Verfügung gestellt?

Wenn ja, wie schaut da die Definition aus? Ich meine, das deklarieren eines int, float, bool etc. schaut ja wie folgt aus:

typ Bezeichner [= Zuweisung]

Wie muss man #define anwenden, um ähnliches zu realisieren, sprich um z.B. eigene Datentypen anzubieten, sodass man später im Programmcode Variablen des eigenen Datentyps anlegen kann:

eigener_datentyp Bezeichner [= Zuweisung]

2.)

Kann man mittels #define auch ähnliche Konstrukte, wie for, while, do-while, switch, if, else, etc. realisieren? Wenn ja, wie?

3.) #define bezeichner(bezeichner_liste) ersatzliste

Wie muss man das verstehen. Für was steht die Bezeichner-Liste und wie verwendet man später eigene mittels #define erzeugte Signalwörter, welche auf diese Art und Weise erzeugt wurden?

####################################

Ich danke vielmals im Vorraus!

Gruß

DITTY :):):):)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ergänzend übernehme ich mal Folgendes direkt aus einem anderen Forum:

#define SQUARE(a) a*a

int x = 5;

int y = SQUARE (x+2); /* berechnet wird: y = x + (2*x) + 2 */

Brjane Stroustroup äussert sich in seinem berühmten Buch "Die C++ Programmiersprache" wie folgt:

"Fast jedes Makro demonstriert eine Schwäche in der Programmiersprache, im Programm oder beim Programmierer. Da Makros den Programmtext ändern, bevor der Compiler ihn richtig liest, sind Makros außerdem ein großes Problem für viele Programmierwerkzeuge. Wenn man also Makros benutzt, muß man schlechtere Dienste von Werkzeugen wie Debuggern, Crossreferenz-Werkzeugen und Profilern erwarten."

Link zu diesem Kommentar
Auf anderen Seiten teilen

Wurden auch so die Schlüsselwörter int, float, bool, etc. definiert und zur Verfügung gestellt?
Nein. Kann auch gar nicht sein, weil Define-Direktiven Neues nur auf bereits Bestehendes zurückführen können. Irgendetwas muss also schon vorher da sein.

Wie muss man #define anwenden, um ähnliches zu realisieren, sprich um z.B. eigene Datentypen anzubieten, sodass man später im Programmcode Variablen des eigenen Datentyps anlegen kann:

eigener_datentyp Bezeichner [= Zuweisung]

Dafür brauchst du keine Define-Direktive, da tut's eine Struktur- oder Klassendefinition oder ein Typedef.

Kann man mittels #define auch ähnliche Konstrukte, wie for, while, do-while, switch, if, else, etc. realisieren? Wenn ja, wie?
Ja, kann man, aber glaub mir, das willst du nicht.

Für was steht die Bezeichner-Liste
Präprozessormakros können wie Funktionen eine Parameterliste haben, wobei die Parameter natürlich nur Namen und keine Typen haben. Im Rumpf des Makros kann dann auf diese Parameter Bezug genommen werden. Siehe das a in Crushs Beispiel.

und wie verwendet man später eigene mittels #define erzeugte Signalwörter, welche auf diese Art und Weise erzeugt wurden?
Am Besten gar nicht. Das geht zwar mit Makros, aber so etwas sollte man sich nicht antun.

Makros sind Dumm. Sie kennen keinen Scope, sie erlauben keine Typprüfung, man kann sie nicht überladen, sie erschweren das Debugging. Fehler in Makros sind zum Teil sehr schwer zu finden.

Von seltene benötigten Ausnahmen abgesehen, gibt es nur einen einzigen Einsatzzweck von Makros in C++: Include-Guards für Headerdateien, also das #ifndef/#define/#endif-Gerüst, das Mehrfacheinbindungen desselben Headers verhindert.

Von allen anderen Anwendungen von Makros sollten gerade Anfänger meiner Meinung nach die Finger lassen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 3 Jahre später...

Sers,

Hab da ein neues Projekt am laufen und bzgl. #defines eine Frage.

define schafft keine Schlüsselwörter sondern ist nur eine einfache Textersetzung.

Ok, bereits reservierte Wörter zu redefinieren scheint wirklich nicht zu gehen.

Was ich aber gerne machen würde ist, Zeichen und Zeichenketten zu definieren. Also etwa

#define ^ *
oder
#define := =
oder auch ganze Zeichenketten:
#define "DO i = 1, 4711 {...} ENDDO" "for(i=1;i<=4711;++i){{...}}"
Es heißt ja, dass der Präprozessor bzw. die Präprozessordirektive #define nichts weiteres macht, als entsprechende Definitionen vor dem eigentlichen Compilieren im Quelltext zu ersetzen / übersetzen. Ich suche eine Möglichkeit, sich hier nicht nur auf klassische Symbolwörter (also Wörter nur aus Buchstaben und Zahlen) zu beschränken. Geht das irgendwie, den #define-Befehl oder andere Mittel von C/C++ zum übersetzen von Text zu verwenden? Auf Codegeneratoren und / oder Übersetzer-Tools möchte ich nicht zurückgreifen, sondern das Ganze allein mit C/C++-Mitteln realisieren, sodass meine Quelltexte dann auch entsprechend mit beliebigen C/C++-Compilern übersetzt werden können. Und, gibt es nicht doch eine Möglichkeit bereits reservierte Wörter, wie "int" zu redefinieren?, etwa:
struct|class INT

{

  public:

    int var;

};


#define int INT()

Damit könnte ich aus skalaren Typen, wie int z.B. Struktur- bzw. Klassenobjekte machen, ähnlich wie in C#.

Grüße

Schlitzauge :)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Was ich aber gerne machen würde ist, Zeichen und Zeichenketten zu definieren.
Geht nicht. Das Präprozessorsymbol, das #define erzeugt, muss den Regeln für Bezeichner folgen.

Auf Codegeneratoren und / oder Übersetzer-Tools möchte ich nicht zurückgreifen, sondern das Ganze allein mit C/C++-Mitteln realisieren, sodass meine Quelltexte dann auch entsprechend mit beliebigen C/C++-Compilern übersetzt werden können.
Das stellt sich spätestens dann als schlechte Idee heraus, wenn der Compiler über Fehler meckert, die wegen der Makro-Orgien im ursrpünglichen Code gar nicht zu finden sind.

Und, gibt es nicht doch eine Möglichkeit bereits reservierte Wörter, wie "int" zu redefinieren?
Wer hat denn gesagt, dass das nicht geht?

#define int INT()

Damit könnte ich aus skalaren Typen, wie int z.B. Struktur- bzw. Klassenobjekte machen, ähnlich wie in C#.

Nö, könntest du nicht.

Ich kann dir nur deutlichst raten: Lass das. Dafür sind Makros nicht gedacht.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Es ist vielmehr ein Machbarkeitsexperiment, ob da je was ernsthaftes drauß wird, wohl eher nicht.

Mich interessieren einfach mal die Grenzen und ob man nicht doch die eine oder andere Grenze sprengen bzw. erweitern könnte. :)

Falls wer Ideen dazu hat, bitte...

Wer hat denn gesagt, dass das nicht geht?

Ja? Hab ich ja nicht behauptet. Wie würde sowas aussehen?

Ich kann mit #define und typedefs "neue" Typen festlegen oder bestehende "umbenennen", aber dann eben nur andersgeschrieben. Ich wollte gerne sowas wie eine Typenerweiterung von int und Co. praktizieren. Also dass man weiterhin entsprechend der C/C++-Syntax eine int-Variable anlegen kann, z.B.:

int var1 = 0;

var1 dann aber eben nicht nur eine int-Variable ist, sondern ein struct / class mit gleichen Typ-Namen int.

Wenn das irgendwie gehen sollte, wäre ich sehr daran interessiert, thx.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ja? Hab ich ja nicht behauptet.
Doch, hast du:

Ok, bereits reservierte Wörter zu redefinieren scheint wirklich nicht zu gehen.

Wie würde sowas aussehen?
#define int wasauchimmer
Also dass man weiterhin entsprechend der C/C++-Syntax eine int-Variable anlegen kann, z.B.:
int var1 = 0;

var1 dann aber eben nicht nur eine int-Variable ist, sondern ein struct / class mit gleichen Typ-Namen int.

Das Problem dabei ist, dass sich dein neuer int nicht genauso verhält wie ein richtiger int. Und sobald dein Makro auf Code losgelassen wird, der sich auf eben dieses Verhalten von int verlässt, knallt es.

Link zu diesem Kommentar
Auf anderen Seiten teilen


#define int wasauchimmer

#include <iostream>

using namespace std;


int main(int argc, char* argv[])

{


  #define int float


  int test1 = 5.458;


  cout << test1 << endl;


  #define int int


  int test2 = 5.458;


  cout << test2;


  getchar();


  return 0;

}
Dein Hinweis war top. Ig werd bekloppt, dass funktioniert ja wirklich. Komisch. Ich hatte es irgendwie die ganze Zeit in Erinnerung, dass das nicht geht bzw. der Compiler seinen Dienst quitiert, weil bereits reservierte Schlüsselwörter manipuliert werden. Vlt. liegts auch einfach nur daran, dass man sowas eigentlich nicht macht und ich das mal so gelernt habe. Ok, wieder was dazugelernt. EDIT: Ok, mit typedefs kann man sowas aber leider nicht machen.
Das Problem dabei ist, dass sich dein neuer int nicht genauso verhält wie ein richtiger int. Und sobald dein Makro auf Code losgelassen wird, der sich auf eben dieses Verhalten von int verlässt, knallt es.
Richtig, deshalb geht mein Gedanke auch in Richtung Bereichskapselung a´la OpenMP, dann sollte auch nichts mehr knallen. Na perfekt, fehlt nur noch die Möglichkeit Sonderzeichen zu redefinieren, halt sowas:
#define := =

#define ^ *

Hier getestet quitiert der Compiler aber den Vorgang, da kein Bezeichner:

[C++ Fehler] Unit1.cpp(5): E2153 Für die Define-Anweisung ist ein Bezeichner erforderlich.

Gibts da nicht Möglichkeiten???

Bearbeitet von Schlitzauge
Link zu diesem Kommentar
Auf anderen Seiten teilen

Komisch. Ich hatte es irgendwie die ganze Zeit in Erinnerung, dass das nicht geht bzw. der Compiler seinen Dienst quitiert, weil bereits reservierte Schlüsselwörter manipuliert werden.
Wie sollte er? Der Compiler bekommt davon überhaupt nichts mit.

Richtig, deshalb geht mein Gedanke auch in Richtung Bereichskapselung a´la OpenMP, dann sollte auch nichts mehr knallen.
Dann kannst du aber nicht den normalen C++-Präprozessor nehmen. Der macht, wie gesagt, nur eine stumpfe Textersetzung, und ist für solche Vorhaben das falsche Werkzeug.

Gibts da nicht Möglichkeiten???

Wie bereits gesagt, das Präprozessorsymbol muss den Anforderungen eines Bezeichners genügen. := ist kein Bezeichner, und ^ auch nicht.
Link zu diesem Kommentar
Auf anderen Seiten teilen

Wie sollte er? Der Compiler bekommt davon überhaupt nichts mit.

Hab ich gerade in meiner Selbsterkenntnis selber bemerkt: :D

Ig werd bekloppt, dass funktioniert ja wirklich.

Das habe ich mir schon fast gedacht. Schade, wäre ein ziemlich mächtiger Präprozessor gewesen und würde mir viel Arbeit bei meinem Vorhaben ersparen. :)

Da werde ich um externe Tools wohl nicht drumherum kommen...

Falls doch noch wer Ideen oder vermeintliche "Unlösungen" dazu finden sollte, bitte...

Ich hab jetzt zumindets einige Ansätze, die ich weiterverfolgen werde...

Thx, Grüße

Schlitzauge :)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Schade, wäre ein ziemlich mächtiger Präprozessor gewesen und würde mir viel Arbeit bei meinem Vorhaben ersparen. :)
Nein, der C++-Präprozessor ist wirklich eher einfach.

Falls doch noch wer Ideen oder vermeintliche "Unlösungen" dazu finden sollte, bitte...
Bastel dir doch deinen eigenen Präprozessor, der tut, was du willst.
Link zu diesem Kommentar
Auf anderen Seiten teilen

Nein, der C++-Präprozessor ist wirklich eher einfach.

Naja, zumindest mächtiger als jeden anderen den ich kenne (Pascal, C#, Fortran, etc.). :D

Bastel dir doch deinen eigenen Präprozessor, der tut, was du willst.

Ganz im Ernst? Geht das, also so, dass man das direkt dann in C/C++ nutzen kann (also mit jedem C/C++-kompatiblen Compiler)???

Da würde ich gerne mal ein Beispiel sehen. Wüsste jetzt nicht, wonach ich da googlen soll...

Link zu diesem Kommentar
Auf anderen Seiten teilen

Naja, zumindest mächtiger als jeden anderen den ich kenne (Pascal, C#, Fortran, etc.).
Du wirfst hier die Makro-Fähigkeiten einer Sprache mit dem Werkzeug, das diese umsetzt, durcheinander. C# hat keinen Präprozessor. Es braucht auch keinen.

Geht das, also so, dass man das direkt dann in C/C++ nutzen kann (also mit jedem C/C++-kompatiblen Compiler)???
Ein Präprozessor ist einfach nur ein Programm, das Daten einliest, verarbeitet und wieder ausgibt. Da steckt doch keine Magie dahinter.

Schau dir doch mal an, wie Qt das mit seinem moc macht. Das ist auch nur ein Programm, das Qt-Code nimmt und daraus ganz normales C++ macht. Das wird dann eben einfach in die Toolchain integriert.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...