Jeśli mam plik source.c ze strukturą:
struct a {
int i;
struct b {
int j;
}
};
Jak można użyć tej struktury w innym pliku (tj. func.c
)?
Czy powinienem utworzyć nowy plik nagłówkowy, zadeklarować tam strukturę i dołączyć ten nagłówek func.c
?
A może powinienem zdefiniować całą strukturę w pliku nagłówkowym i dołączyć ją do obu source.c
i func.c
? Jak można zadeklarować strukturę extern
w obu plikach?
Powinienem to typedef
zrobić? Jeśli tak to jak?
struct b
, ale wtedy twoja strukturaa
deklaruje typ, który nie jest używany (prawdopodobnie powinieneś zdefiniować nazwę elementu, być możek
po wewnętrznym nawiasie zamykającym i przed średnikiemOdpowiedzi:
jeśli ta struktura ma być używana przez jakiś inny plik func.c, jak to zrobić?
Kiedy typ jest używany w pliku (np. Plik func.c), musi być widoczny. Najgorszym sposobem na zrobienie tego jest skopiowanie i wklejenie go do każdego pliku źródłowego tego potrzebnego.
Właściwym sposobem jest umieszczenie go w pliku nagłówkowym i dołączenie tego pliku nagłówkowego, gdy jest to potrzebne.
czy powinniśmy otworzyć nowy plik nagłówkowy i zadeklarować tam strukturę i dołączyć ten nagłówek do func.c?
Jest to rozwiązanie, które lubię bardziej, ponieważ sprawia, że kod jest wysoce modułowy. Zakodowałbym twoją strukturę jako:
Funkcje wykorzystujące tę strukturę umieściłbym w tym samym nagłówku (funkcja, która jest „semantycznie” częścią jej „interfejsu”).
Zwykle mogłem nazwać plik po nazwie struktury i użyć tej nazwy ponownie, aby wybrać definicje ochrony nagłówka.
Jeśli chcesz zadeklarować funkcję za pomocą wskaźnika do struktury, nie będziesz potrzebować pełnej definicji struktury. Prosta deklaracja forward, taka jak:
Wystarczy, a to zmniejszy sprzężenie.
czy też możemy zdefiniować całkowitą strukturę w pliku nagłówkowym i zawrzeć ją zarówno w source.c, jak i func.c?
Jest to inny sposób, nieco łatwiejszy, ale mniej modułowy: niektóre kody wymagające do działania tylko Twojej struktury będą nadal musiały zawierać wszystkie typy.
W C ++ może to prowadzić do interesujących komplikacji, ale jest to poza tematem (brak tagu C ++), więc nie będę się rozpisywał.
następnie jak zadeklarować tę strukturę jako zewnętrzną w obu plikach. ?
Być może nie widzę sensu, ale Greg Hewgill ma bardzo dobrą odpowiedź w swoim poście Jak zadeklarować strukturę w nagłówku, która ma być używana przez wiele plików w c? .
powinniśmy więc wpisać to jak?
Powodem jest to, że zarządzanie strukturą w C może być uciążliwe: musisz zadeklarować słowo kluczowe struct wszędzie, gdzie jest używane:
Podczas gdy typedef pozwoli ci napisać go bez słowa kluczowego struct.
Jest to ważne, nadal zachować nazwę struktury. Pisanie:
po prostu utworzy anonimową strukturę z nazwą wpisaną w typoszeregu i nie będziesz w stanie jej zadeklarować. Dlatego zachowaj następujący format:
W ten sposób będziesz mógł używać MyStruct wszędzie tam, gdzie chcesz uniknąć dodawania słowa kluczowego struct i nadal używać MyStructTag, gdy typedef nie zadziała (tj. Deklaracja do przodu)
Edytować:
Poprawiono błędne założenie dotyczące deklaracji struktury C99, jak słusznie zauważył Jonathan Leffler .
Edycja 2018-06-01:
Craig Barnes przypomina nam w swoim komentarzu, że nie trzeba zachowywać oddzielnych nazw dla nazwy struktury „tag” i jej nazwy „typedef”, tak jak to zrobiłem powyżej dla przejrzystości.
Rzeczywiście, powyższy kod można by napisać jako:
IIRC, to właśnie robi C ++ z prostszą deklaracją struktury, za kulisami, aby zachować zgodność z C:
Wracając do C, widziałem oba zastosowania (oddzielne nazwy i te same nazwy) i żadna z nich nie ma wad, o których wiem, więc użycie tej samej nazwy ułatwia czytanie, jeśli nie używasz oddzielnych „przestrzeni nazw” w C dla struktur i innych symboli .
źródło
struct
tagu itypedef
nazwy. C używa innej przestrzeni nazw dlastruct
tagów, więc możesz używaćMyStruct
obu.W przypadku definicji struktury, która ma być używana w więcej niż jednym pliku źródłowym, zdecydowanie należy umieścić ją w pliku nagłówkowym. Następnie dołącz ten plik nagłówkowy do dowolnego pliku źródłowego, który wymaga takiej struktury.
extern
Deklaracja nie służy do definicji struktury, ale zamiast tego jest używany do deklaracji zmiennych (czyli jakaś wartość danych z typem konstrukcji, które zostały zdefiniowane). Jeśli chcesz użyć tej samej zmiennej w więcej niż jednym pliku źródłowym, zadeklaruj ją tak, jakextern
w pliku nagłówkowym, takim jak:Następnie w jednym pliku źródłowym zdefiniuj rzeczywistą zmienną:
Jeśli zapomnisz o tym zrobić lub przypadkowo zdefiniujesz to w dwóch plikach źródłowych, linker poinformuje Cię o tym.
źródło
GLOBAL
jakoextern
lub nic u góry nagłówka, a następnie zadeklarowanie zmiennych jakoGLOBAL struct a myAValue;
. Z większości plików źródłowych ustalasz, która#define GLOBAL extern
wersja ma być używana ( deklarując zmienne) i z dokładnie jednego pliku źródłowego powoduje to użycie pustej definicji, więc zmienne są zdefiniowane .ah:
gotowe, teraz wystarczy dołączyć ah do plików, w których chcesz używać tej struktury.
źródło