Ich lerne C und finde, dass jemand eine Struktur definiert hat, deren Strukturname _ davor steht. Ich habe es zum ersten Mal gesehen, kann mir jemand etwas mehr darüber erzählen? Warum würde jemand _aStructName anstelle von aStructName verwenden, was sind die Vorteile?
struct _huffmanNode {
int value;
uint32_t frequency;
int hasChild;
struct _huffmanNode *child[2];
struct _huffmanNode *next;
};
Ebenso finde ich jemanden, der diese Art von Namenskonvention im folgenden Code verwendet:
typedef struct HuffCode_ {
unsigned char used;
unsigned short code;
unsigned char size;
} HuffCode;
Es gibt keinen Vorteil im Benutzercode, es ist nur hässlich. Im zweiten Beispiel ist die HuffCode_
ist nicht einmal notwendig, da die struct
Typ ist bereits durch die benannt typedef
.
Die einzigen Orte, an denen dies nützlich sein kann, sind:
- Wann
StructName
wird bereits verwendet, StructName_
gibt einen anderen Namen (aber Sie sollten sich wirklich einen besseren Namen einfallen lassen).
- Bezeichner in der C-Standardbibliothek, die nicht durch den Standard definiert sind, sollten nicht mit Benutzercode-Bezeichnern in Konflikt geraten. Daher verwenden Autoren von C-Bibliotheken die
_
Präfix in der Hoffnung, dass die Benutzer das nicht verwenden werden. Leider tun das einige Benutzer.
- Bei sehr alten Compilern kann es sinnvoll sein, die
struct
ein anderer Name als in der verwendet wird typedef
. Du brauchst beides typedef
und den anderen Namen, wenn Sie eine verknüpfte Struktur erstellen (Beispiel).
Ich denke, dies geschieht hauptsächlich aufgrund der sehr falschen Vorstellung, dass eine Struktur und ein Typ nicht denselben Namen haben können. Mit anderen Worten, das irgendwie
struct MyStruct;
typedef struct MyStruct MyStruct;
wird auf seltsame Weise kollidieren, weil die struct
und die typedef
denselben Namen haben. Dies ist in C falsch. Der Name einer Struktur wird als a betrachtet Schild, während ein typedef einen Typnamen erstellt. Diese leben in zwei verschiedenen Namespaces und werden nicht kollidieren. Meiner Meinung nach ist es viel sinnvoller, wenn das Tag der Struktur mit dem Typedef identisch ist, vorausgesetzt, Sie verwenden überhaupt ein Typedef. In C müssen Sie immer mit dem Schlüsselwort struct auf eine Struktur verweisen. Zum Beispiel, wenn Sie definieren
struct MyStruct;
aber keine Typedef machen, dann ist folgendes ungültig:
void myfunction()
{
MyStruct var; /* compiler error: MyStruct is not defined. */
struct MyStruct var2; /* this is OK, MyStruct is a valid name for a struct. */
}
Wenn Sie Variablen (oder Argumente) vom Typ definieren möchten MyStruct
in C, du muss Geben Sie eine Typdefinition an:
typedef struct MyStruct MyStruct;
void myfunction2()
{
MyStruct var; /* this is ok now */
struct MyStruct var2; /* this is still ok too */
}
In diesem zweiten Beispiel var
und var2
denselben Typ haben, obwohl dies nicht offensichtlich ist. Wenn die Typedef geändert würde, hätten sie tatsächlich nicht mehr den gleichen Typ. Hüten Sie sich davor! Es kann einige interessante Fehler verursachen, wenn sich Typdefinitionen ändern.
In C++ erstellt eine Struct-Definition im Wesentlichen eine implizite typedef
sodass die beiden obigen Codeschnipsel kompiliert werden. In C++ gibt es im Wesentlichen keinen Unterschied zwischen einem Strukturnamen (oder Tag) und einem Typnamen. Dies ist meiner Meinung nach ein weiterer guter Grund, die beiden gleich zu benennen, insbesondere wenn Sie davon ausgehen, dass Ihr C-Modul irgendwann von C++-Code verwendet werden könnte.
Oftmals möchten die Leute in reinem C ihre Strukturen typdefinieren, damit sie nicht so hässlich aussehen. Also nennen sie die Struktur selbst etwas Hässliches und die Typedef etwas Sauberes. Normalerweise ist die Konvention, die ich in der GNU-Welt gesehen habe, folgende:
typedef struct mytype_t
{
int field;
char field2;
} mytype;
Ich verwende eine Variante des zweiten Beispiels:
typedef struct huffcode {
... } HuffCode;
Konvention von Schule 42 (Norminette)
typedef struct s_name
{
...
} t_name;
Beachten Sie, dass alle Bezeichner, die mit einem Unterstrich beginnen, für die Implementierung reserviert sind und nicht für eigene Bezeichner verwendet werden sollten.
– pmg
5. April 2011 um 22:03 Uhr
@pmg: Alle Bezeichner, die mit beginnen zwei Unterstriche sind für die Implementierung reserviert. Alle Bezeichner, die mit einem Unterstrich beginnen, sollten außerhalb des Dateibereichs nicht sichtbar sein (z. B. eine statische globale oder eine interne Struktur).
– Shahbaz
13. April 2012 um 19:45 Uhr