2010-04-09 11 views
9

Widziałem kody źródłowe, które zawsze mają typedef dla struktury i używają tego samego wszędzie, zamiast używać nazwy struktury jako "struct sname" itp. Bezpośrednio?Dlaczego nazwy struktur mają typedef?

Jaki jest tego powód? Czy są w tym jakieś korzyści?

+0

W swojej książce * Expert C Programming *, Peter van der Linden czyni sprawę, że typedefs dla structs są bezużyteczne i nie powinieneś się kłopotać. Lubię to. Wszystko, co robi typedef, oszczędza pisanie 'struct' w kilku miejscach, takich jak deklaracje i prototypy. To nie jest warte zaciemniania. Chcę od razu wiedzieć, kiedy muszę użyć '->' lub '.'. Typedefs sprawia, że ​​jest to trudniejsze. – Jens

Odpowiedz

10

jej łatwiej czytać Box b; niż struct boxtype b;

typedef struct _entry{ 
    char *name; 
    int id; 
} Entry, *EntryP; 

zaletę:
W powyższym typedef, zarówno Entry & EntryP są zdefiniowane oprócz struct _entry.
Tak, EntryP firstentry może być używany zamiast struct _entry *firstentry i jest nieco prostszy do zanalizowania.

Uwaga: Nie tak jak nazwy struktur powinny być typedef INED, ale widocznie jej łatwiejsze do odczytania. Również użycie Entry * vs EntryP jest całkowicie zależne od użytkownika.

+3

Generalnie argumentuję przeciwko typedefs takim jak 'EntryP'. C ma już doskonały sposób zadeklarowania żądanego wskaźnika: 'Entry * firstentry'. –

+1

@Hagglund: Nie ma się o co kłócić :). Jest całkowicie subiektywny, można polubić 'EntryP', podczas gdy inne mogą lubić' Entry * '. –

+1

Zgadzam się, że jest to subiektywne, ale muszę pomyśleć, że nie jest to zalecane, ponieważ eliminuje fakt, że 'firstentry' jest typu' Entry * 'bez żadnego powodu. Chociaż "P" w "EntryP" ma na celu podkreślenie "wskaźnika do", to nadal jest niejednoznaczne, natomiast 'Entry *' nie jest. W każdym razie, uważam, że twój wiersz 'struct entry * firstentry' powinien być' struct _entry * firstentry', zauważ podkreślenie – SiegeX

1

Jest to forma ukrywania informacji i przydatne przy tworzeniu typów nieprzezroczystych. Zobacz: this SO link, aby uzyskać nieco dłuższą odpowiedź.

3

Lubię to zrobić w C:

// in a "public" header file 
typedef struct Example Example; 

// in a "private" header or a source file 
struct Example { ... }; 

Jak to, mam Example jako typ nieprzezroczysty (tj, mogę przekazać jedynie odnośniki do niej około) w ciągu całego mojego kodu, wyjątkiem dla osób kod implementujący swoje operacje, który może zobaczyć, co jest naprawdę zdefiniowane. (Można użyć osobnej nazwy dla typu nieprzezroczystego, ale nie ma żadnej realnej korzyści).

1

Nazwa strukturalna bez nazwy w C wymaga, aby wzorzec "wzorca" był zawsze wszędzie tam, gdzie używana jest nazwa typu, więc większość ludzi używa typedef, aby utworzyć nową nazwę dla typu, który nie musi mieć ciągłego słowa kluczowego struct.

Powodem tego jest czytelność kodu, zmniejszone pisanie i prawdopodobnie również klarowność, ale typedefs może w rzeczywistości zaciemnić informacje na temat typów wskaźników.

Szczerze mówiąc, potrzeba typedef do tworzenia nowych nazw dla struktur jest reliktem i szkoda, że ​​C99 nie podąża za C++ i nie usuwa go.

+0

C99 nie może pozbyć się konieczności 'typedef' aby pozbyć się' struct' z powodu zacofania zgodność. Jest wiele takich kodów jak 'struct Foo {...}; typedef ... Foo; 'który przestałby kompilować. – JeremyP

4

Jest to dziwne dziwactwo w języku C, nazwy znaczników struktury są przechowywane w innym obszarze nazw (tabela symboli). Język C++ pozbył się tego zachowania. Typedef tworzy alias dla typu struktury w globalnej przestrzeni nazw. Więc nie musisz wpisywać "struct" przed nazwą struktury.

Nie jestem pewien, co Ritchie palił, kiedy definiował to zachowanie. Zgaduję, że istnieje jakiś problem z analizatorem składni we wczesnej wersji kompilatora.

+0

Przypuszczam, że to prawdopodobnie uprościło przydzielanie pamięci w pierwszych kompilatorach, co było ważne, gdy wszystko musiało pasować do 128k lub mniej przestrzeni danych. W rzeczywistości w najwcześniejszych kompilatorach C istniała również pojedyncza * globalna * przestrzeń nazw dla nazw członków struktury. Oznaczało to, że 'struct foo' i' struct bar' nie mogą mieć jednocześnie elementu o nazwie "x", który prowadzi bezpośrednio do stylu tagletu ('f_x',' b_x') dla członków struct, które są wspólne dla dzisiejszego dnia w niektórych językach. Kod C –

+0

@Dave: Myślę, że masz rację. Coś palono z nazwami członków struktury. To było za długie, dawno temu umieściłem tę komórkę mózgową w rogu ignorowania. Wow, dlaczego musiał? B? –

2

Jest to tylko do odczytu kodu. typedefs służą tylko do podania nazwy dla typu danych. Zamiast podawać int wszędzie tam, gdzie możesz nazwać go tak, jak chcesz i gdziekolwiek używasz int, możesz po prostu zastąpić go nową nazwą, którą podałeś. To samo dotyczy również konstrukcji.

0

Właściwie nie używam typedef dla struktur. Dlaczego? Ponieważ użyłbym jakiejś konwencji, takiej jak przedrostek s_, aby łatwo zobaczyć, na jaką zmienną patrzę.

Ponieważ używam wielu abstrakcyjnych typów danych, myślę, że dobrym pomysłem byłoby użycie typedef, aby użytkownik naprawdę używał go jako czcionki nieprzezroczystej. Ale w praktyce zawsze używam struct w implementacji.

Powiązane problemy