In Betracht ziehen:
#define MAXROW 20
#define MAXCOL 60
typedef State Grid[MAXROW+2] [MAXCOL+2]
typedef enum state {DEAD,ALIVE} State
Wie verwende ich typedef
und typedef enum
in C? Was macht dieser Teil des Codes?
Benutzer39555
In Betracht ziehen:
#define MAXROW 20
#define MAXCOL 60
typedef State Grid[MAXROW+2] [MAXCOL+2]
typedef enum state {DEAD,ALIVE} State
Wie verwende ich typedef
und typedef enum
in C? Was macht dieser Teil des Codes?
Kaz
typedef enum state {DEAD,ALIVE} State;
| | | | | |^ terminating semicolon, required!
| | | type specifier | | |
| | | | ^^^^^ declarator (simple name)
| | | |
| | ^^^^^^^^^^^^^^^^^^^^^^^
| |
^^^^^^^-- storage class specifier (in this case typedef)
Das typedef
Schlüsselwort ist ein Pseudo-Speicherklassenbezeichner. Syntaktisch wird es an der gleichen Stelle verwendet wie ein Speicherklassenbezeichner extern
oder static
wird genutzt. Mit Lagerung hat das nichts zu tun. Das bedeutet, dass die Deklaration nicht die Existenz von einführt benannte Objektesondern führt Namen ein, die sind Geben Sie Aliase ein.
Nach der obigen Erklärung, die State
Bezeichner wird zu einem Alias für den Typ enum state {DEAD,ALIVE}
. Die Deklaration stellt auch diesen Typ selbst bereit. Das ist es aber nicht typedef
es tun. Irgendein Erklärung, in der enum state {DEAD,ALIVE}
erscheint als Typbezeichner, der diesen Typ in den Gültigkeitsbereich einführt:
enum state {DEAD, ALIVE} stateVariable;
Wenn enum state
wurde zuvor eingeführt typedef
muss so geschrieben werden:
typedef enum state State;
ansonsten der enum
wird neu definiert, was ein Fehler ist.
Wie andere Deklarationen (außer Deklarationen von Funktionsparametern) ist die typedef
Deklaration kann mehrere Deklaratoren haben, getrennt durch ein Komma. Darüber hinaus können sie abgeleitete Deklaratoren sein, nicht nur einfache Namen:
typedef unsigned long ulong, *ulongptr;
| | | | | 1 | | 2 |
| | | | | | ^^^^^^^^^--- "pointer to" declarator
| | | | ^^^^^^------------- simple declarator
| | ^^^^^^^^^^^^^-------------------- specifier-qualifier list
^^^^^^^---------------------------------- storage class specifier
Dies typedef
führt zwei Typnamen ein ulong
und ulongptr
basierend auf unsigned long
Typ, der in der Bezeichner-Qualifizierer-Liste angegeben ist. ulong
ist nur ein direkter Alias für diesen Typ. ulongptr
wird als Zeiger auf deklariert unsigned long
Danke an die *
Syntax, die in dieser Rolle eine Art Typkonstruktionsoperator ist, der bewusst das Unäre nachahmt *
für die Dereferenzierung von Zeigern, die in Ausdrücken verwendet werden. Mit anderen Worten ulongptr
ist ein Alias für den “Zeiger auf unsigned long
” Typ.
Alias bedeutet das ulongptr
ist kein eigenständiger Typ aus unsigned long *
. Dies ist ein gültiger Code, der keine Diagnose erfordert:
unsigned long *p = 0;
ulongptr q = p;
Die Variablen q
und p
habe genau den gleichen typ.
Das Aliasing von typedef
ist nicht textlich. Zum Beispiel wenn user_id_t
ist ein typedef
Bezeichnung für den Typ int
können wir dies nicht einfach tun:
unsigned user_id_t uid; // error! programmer hoped for "unsigned int uid".
Dies ist eine Liste mit ungültigen Typbezeichnern, Kombination unsigned
mit einem Typedef-Namen. Das Obige kann mit dem C-Präprozessor durchgeführt werden:
#define user_id_t int
unsigned user_id_t uid;
wodurch user_id_t
wird zum Token makro-erweitert int
vor Syntaxanalyse und Übersetzung. Während dies wie ein Vorteil erscheinen mag, ist es ein falscher; Vermeiden Sie dies in neuen Programmen.
Unter den Nachteilen, dass es für abgeleitete Typen nicht gut funktioniert:
#define silly_macro int *
silly_macro not, what, you, think;
Diese Deklaration deklariert nicht what
, you
und think
als vom Typ “Zeiger auf int”, weil die Makroerweiterung ist:
int * not, what, you, think;
Der Typbezeichner ist int
und die Deklaratoren sind *not
, what
, you
und think
. So not
hat den erwarteten Zeigertyp, die übrigen Bezeichner jedoch nicht.
Und das ist wahrscheinlich 99% von allem typedef
und Typ-Aliasing in C.
Sollte es nicht sein ulongptr q = p
dass sowohl p als auch q genau den gleichen Typ haben? So wie du geschrieben hast, kannst du es haben ulong *q = p
und das hätte genau den gleichen typ wie unsigned long *p
– Bhargav
25. August 2016 um 5:33 Uhr
@Bhargav Du hast recht, das ist ein Tippfehler. ulongptr *q = p
erfordert eine Diagnose; es ist eine Konvertierung zwischen unterschiedlichen Zeigertypen ohne Umwandlung.
– Kas
25. August 2016 um 5:51 Uhr
+2 für gottähnliche ASC-Kunstfertigkeiten.
– kmiklas
1. Februar 2019 um 16:20 Uhr
Pandrei
typedef
definiert einen neuen Datentyp. Sie können also haben:
typedef char* my_string;
typedef struct{
int member1;
int member2;
} my_struct;
Jetzt können Sie also Variablen mit diesen neuen Datentypen deklarieren
my_string s;
my_struct x;
s = "welcome";
x.member1 = 10;
Zum enum
liegen die Dinge etwas anders – betrachten Sie die folgenden Beispiele:
enum Ranks {FIRST, SECOND};
int main()
{
int data = 20;
if (data == FIRST)
{
//do something
}
}
verwenden typedef enum
erstellt einen Alias für einen Typ:
typedef enum Ranks {FIRST, SECOND} Order;
int main()
{
Order data = (Order)20; // Must cast to defined type to prevent error
if (data == FIRST)
{
//do something
}
}
wie werden im zweiten beispiel 20 und first oder second verglichen?
– Benutzer39555
6. Dezember 2013 um 15:10 Uhr
enum ist ein ganzzahliger Typ; Der erste Wert in der Aufzählung ist 0 (sofern nicht anders angegeben), der zweite ist der erste Wert + 1 (in diesem Fall 0 + 1) und so weiter. Wenn Sie eine Variable vom Typ enum_data_type deklarieren, können Sie ihr nur Werte zuweisen, die in der Aufzählung vorhanden sind …. der Compiler führt die Überprüfung durch.
– Pandrei
6. Dezember 2013 um 15:13 Uhr
Also im 2. Beispiel, wenn (data==FIRST) falsch ist, wird es wahr sein, wenn ich int data=0 zuweise?
– Benutzer39555
6. Dezember 2013 um 15:30 Uhr
typedef
definiert keinen neuen Datentyp; es definiert einen Bezeichner für einen vorhandenen Datentyp.
– Kas
7. Januar 2016 um 23:26 Uhr
Verwenden typedef
mit einer Aufzählung wirkt sich nicht auf die Eigenschaften der Aufzählung aus. Ihr zweites Beispielpaar: erstens ist es ein Ablenkungsmanöver, beim ersten hätte man schreiben können enum Ranks data = 20;
Anstatt von int data = 20;
. Aber in beiden Fällen ist die Abtretung erlaubt 20
auf eine Variable vom Typ enum, ist dies kein Fehler.
– MM
25. August 2016 um 6:39 Uhr
J-Dizzle
EIN Typdefist nur ein Alias -
Wie hier, wo diese “type_name” typedef für eine “struct structure_name” verwendet wird – codesdope.com/cpp-typedef
– J-Dizzle
14. August um 21:42 Uhr
Willkommen bei SO! Die Frage ist etwas zu einfach und wurde höchstwahrscheinlich bereits auf SO gestellt. Mit welchem Material lernst du C? Sie sollten ein besseres Material finden, das diese Frage beantwortet, sonst verzetteln Sie sich zu sehr in Fragen. Suchen Sie nach den besten C-Tutorials bei Google und SO.
– Ciro Santilli OurBigBook.com
6. Dezember 2013 um 14:51 Uhr
Eigentlich kenne ich grundlegendes C, aber diese Grid-Anweisung ist das, was ich nicht klar bekomme
– Benutzer39555
6. Dezember 2013 um 14:55 Uhr