Sind typedef und #define in c gleich?

Lesezeit: 6 Minuten

ich frage mich, ob typedef und #define sind die gleichen in c?

Benutzeravatar von Andreas Grech
Andreas Gretsch

typedef gehorcht den Bereichsregeln genauso wie Variablen, wohingegen define bleibt gültig bis zum Ende der Übersetzungseinheit (oder bis ein Matching undef).

Außerdem kann man einiges damit machen typedef damit geht es nicht define.
Zum Beispiel:

typedef int* int_p1;
int_p1 a, b, c;  // a, b, c are all int pointers

#define int_p2 int*
int_p2 a, b, c;  // only the first is a pointer, because int_p2
                 // is replaced with int*, producing: int* a, b, c
                 // which should be read as: int *a, b, c
typedef int a10[10];
a10 a, b, c;  // create three 10-int arrays
typedef int (*func_p) (int);
func_p fp;  // func_p is a pointer to a function that
            // takes an int and returns an int

Benutzeravatar von pmg
pmg

Nein.

#define ist ein Präprozessor-Token: Der Compiler selbst wird es nie sehen.
typedef ist ein Compiler-Token: Der Präprozessor kümmert sich nicht darum.

Sie können das eine oder andere verwenden, um den gleichen Effekt zu erzielen, aber es ist besser, das richtige für Ihre Bedürfnisse zu verwenden

#define MY_TYPE int
typedef int My_Type;

Wenn es „haarig“ wird, macht es das richtige Werkzeug richtig

#define FX_TYPE void (*)(int)
typedef void (*stdfx)(int);

void fx_typ(stdfx fx); /* ok */
void fx_def(FX_TYPE fx); /* error */

  • Nach der typedef stdfxsind gültige Objekte dieses Typs Zeiger auf Funktionen, die ein int empfangen und keinen Wert zurückgeben.

    – pmg

    14. Juni 2015 um 17:53 Uhr


  • Warum würde #define im Fall eines Funktionszeigers als Argument fehlschlagen?

    – Allahjane

    31. Dezember 2016 um 23:02 Uhr

  • @Allahjane: die Erweiterung wird void fx_def(void (*)(int) fx);; die richtige Deklaration ist void fx_def(void (*fx)(int));.

    – pmg

    1. Januar 2017 um 10:18 Uhr

  • Funktionszeiger sind mit Makros machbar, nur wenn Sie bereit sind, die Syntax aufzugeben: #define FX_TYPE(f) void (*f)(int). Sie würden dann Ihre Funktion wie folgt deklarieren: void fx_def(FX_TYPE(fx));

    – Teller

    2. April 2017 um 15:50 Uhr


Nein, sie sind nicht gleich. Zum Beispiel:

#define INTPTR int*
...
INTPTR a, b;

Nach der Vorverarbeitung erweitert sich diese Zeile zu

int* a, b;

Hoffentlich sehen Sie das Problem; nur a wird den Typ haben int *; b wird zur Ebene erklärt int (weil die * dem Deklarator zugeordnet ist, nicht dem Typbezeichner).

Vergleichen Sie das mit

typedef int *INTPTR;
...
INTPTR a, b;

In diesem Fall beides a und b wird Typ haben int *.

Es gibt ganze Klassen von Typedefs, die nicht mit einem Präprozessor-Makro emuliert werden können, wie z. B. Zeiger auf Funktionen oder Arrays:

typedef int (*CALLBACK)(void);
typedef int *(*(*OBNOXIOUSFUNC)(void))[20]; 
...
CALLBACK aCallbackFunc;        // aCallbackFunc is a pointer to a function 
                               // returning int
OBNOXIOUSFUNC anObnoxiousFunc; // anObnoxiousFunc is a pointer to a function
                               // returning a pointer to a 20-element array
                               // of pointers to int

Versuchen Sie das mit einem Präprozessor-Makro.

Benutzeravatar von Yochai Timmer
Yocha Timmer

#definieren definiert Makros.
Typdef definiert Typen.

Nun, da ich das sage, hier sind ein paar Unterschiede:

Mit #definieren Sie können Konstanten definieren, die zur Kompilierzeit verwendet werden können. Die Konstanten können mit verwendet werden #ifdef um zu überprüfen, wie der Code kompiliert wird, und bestimmten Code gemäß Kompilierungsparametern zu spezialisieren.
Sie können auch verwenden #definieren um Miniatur-Suchen und Ersetzen zu erklären Makrofunktionen.

Typdef kann verwendet werden, um Typen Aliase zu geben (was Sie wahrscheinlich tun könnten #definieren auch), aber es ist sicherer wegen der Find-and-Replace-Natur von #definieren Konstanten.
Außerdem können Sie verwenden Vorwärtserklärung mit Typdef Dadurch können Sie einen Typ deklarieren, der verwendet wird, aber noch nicht mit der Datei verknüpft ist, in die Sie schreiben.

Präprozessor-Makros (“#define‘s”) sind ein lexikalisches Ersetzungswerkzeug à la “Suchen und Ersetzen”. Sie sind völlig agnostisch gegenüber der Programmiersprache und haben kein Verständnis dafür, was Sie zu tun versuchen. Sie können sie sich als verherrlichte Mechanik zum Kopieren und Einfügen vorstellen – – Gelegentlich ist das nützlich, aber Sie sollten es mit Vorsicht verwenden.

Typedefs sind eine Funktion der C-Sprache, mit der Sie Aliase für Typen erstellen können. Dies ist äußerst nützlich, um komplizierte zusammengesetzte Typen (wie Strukturen und Funktionszeiger) lesbar und handhabbar zu machen (in C++ gibt es sogar Situationen, in denen Sie muss typedef ein Typ).

Zu (3): Sie sollten Sprachfunktionen immer Präprozessor-Makros vorziehen, wenn dies möglich ist! Verwenden Sie also immer typedefs für Typen und konstante Werte für Konstanten. Auf diese Weise kann der Compiler tatsächlich sinnvoll mit Ihnen interagieren. Denken Sie daran, dass der Compiler Ihr Freund ist, also sollten Sie ihm so viel wie möglich mitteilen. Präprozessor-Makros machen genau das Gegenteil, indem sie versteckt Ihre Semantik aus dem Compiler.

  • Können Sie ein Beispiel in C++ nennen, wo Sie einen Typ typedef müssen? Ich bin nur neugierig darauf.

    – jyz

    30. April 2013 um 15:42 Uhr


  • @jyzuz: Es gibt etwas, wenn Sie möchten, dass eine Member-Funktion ein Array von Funktionszeigern oder ähnliches zurückgibt – wenn Sie versuchen, den Typ zu buchstabieren, sagt GCC tatsächlich: “Sie müssen eine Typedef verwenden”.

    – Kerrek SB

    30. April 2013 um 15:51 Uhr

Benutzeravatar von bta
bta

Sie sind sehr unterschiedlich, obwohl sie oft verwendet werden, um benutzerdefinierte Datentypen zu implementieren (was ich bei dieser Frage annehme).

Wie pmg schon erwähnt hat, #define wird vom Präprozessor verarbeitet (wie ein Ausschneiden-und-Einfügen-Vorgang), bevor der Compiler den Code sieht, und typedef wird vom Compiler interpretiert.

Einer der Hauptunterschiede (zumindest wenn es um die Definition von Datentypen geht) ist das typedef ermöglicht eine spezifischere Typprüfung. Zum Beispiel,

#define defType int
typedef int tdType

defType x;
tdType y;

Hier sieht der Compiler die Variable x als int, aber die Variable y als einen Datentyp namens „tdType“, der zufällig die gleiche Größe wie ein int hat. Wenn Sie eine Funktion schreiben, die einen Parameter vom Typ defType verwendet, könnte der Aufrufer ein normales int übergeben, und der Compiler würde den Unterschied nicht erkennen. Wenn die Funktion stattdessen einen Parameter vom Typ tdType annehmen würde, würde der Compiler sicherstellen, dass während Funktionsaufrufen eine Variable des richtigen Typs verwendet wird.

Außerdem haben einige Debugger die Fähigkeit, damit umzugehen typedefs, was viel nützlicher sein kann, als alle benutzerdefinierten Typen als ihre zugrunde liegenden primitiven Typen aufzulisten (wie es wäre, wenn #define wurde stattdessen verwendet).

  • Können Sie ein Beispiel in C++ nennen, wo Sie einen Typ typedef müssen? Ich bin nur neugierig darauf.

    – jyz

    30. April 2013 um 15:42 Uhr


  • @jyzuz: Es gibt etwas, wenn Sie möchten, dass eine Member-Funktion ein Array von Funktionszeigern oder ähnliches zurückgibt – wenn Sie versuchen, den Typ zu buchstabieren, sagt GCC tatsächlich: “Sie müssen eine Typedef verwenden”.

    – Kerrek SB

    30. April 2013 um 15:51 Uhr

Nein.
Typdef ist ein C-Schlüsselwort, das einen Alias ​​für einen Typ erstellt.
#define ist eine Vorprozessoranweisung, die vor der Kompilierung ein Textersetzungsereignis erzeugt. Wenn der Compiler zum Code gelangt, ist das ursprüngliche „#defined“-Wort nicht mehr vorhanden. #define wird hauptsächlich für Makros und globale Konstanten verwendet.

  • Die Verwendung des Begriffs “Zeiger” könnte hier zu Verwirrung führen.

    Benutzer59634

    3. November 2009 um 10:02 Uhr

  • Einverstanden. Aus diesem Grund bin ich zurückgegangen und habe einen Link zu typdef auf MSDN hinzugefügt – nur für den Fall, dass jemand in Zukunft diese Frage verwenden wird, um herauszufinden, was typdef ist. Aber vielleicht sollte ich das Wort ändern…

    – Reisender Techniker

    3. November 2009 um 10:06 Uhr

1423920cookie-checkSind typedef und #define in c gleich?

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

Privacy policy