Natknąłem się na kod zawierający:
struct ABC {
unsigned long array[MAX];
} abc;
Kiedy stosowanie takiej deklaracji ma sens?
c
arrays
coding-style
struct
Joe.Z
źródło
źródło
Kolejną zaletą jest to, że abstrahuje rozmiar, więc nie musisz używać
[MAX]
całego kodu wszędzie tam, gdzie deklarujesz taki obiekt. Można to również osiągnąć za pomocątypedef char ABC[MAX];
ale wtedy masz znacznie większy problem: musisz być świadomy, że
ABC
jest to typ tablicowy (nawet jeśli nie możesz tego zobaczyć, kiedy deklarujesz zmienne typuABC
), inaczej zostaniesz ukąszony faktem, żeABC
będzie to oznaczać coś innego na liście argumentów funkcji a w deklaracji / definicji zmiennej.Kolejną zaletą jest to, że struktura pozwala później dodać więcej elementów, jeśli zajdzie taka potrzeba, bez konieczności przepisywania dużej ilości kodu.
źródło
Możesz skopiować strukturę i zwrócić strukturę z funkcji.
Nie możesz tego zrobić z tablicą - chyba że jest częścią struktury!
źródło
Możesz to skopiować w ten sposób.
struct ABC a, b; ........ a = b;
W przypadku tablicy należałoby użyć funkcji memcpy lub pętli do przypisania każdego elementu.
źródło
Możesz użyć struct, aby utworzyć nowy typ danych, taki jak ciąg . możesz zdefiniować:
struct String { char Char[MAX]; };
lub możesz utworzyć Listę danych, których możesz użyć jako argument funkcji lub zwrócić ją w swoich metodach. Struktura jest bardziej elastyczna niż tablica, ponieważ może obsługiwać niektóre operatory, takie jak =, i możesz zdefiniować w niej niektóre metody.
Mam nadzieję, że to Ci się przyda :)
źródło
Inną zaletą stosowania takiego znaku
struct
jest to, że wymusza bezpieczeństwo typu wszędzie tam, gdzie takistruct
jest używany; zwłaszcza jeśli masz dwa typy składające się z tablic o tym samym rozmiarze używanych do różnych celów, typy te pomogą Ci uniknąć przypadkowego niewłaściwego użycia tablicy.Jeśli nie zawiniesz tablicy w a
struct
, nadal możesz zadeklarowaćtypedef
dla niej a: ma to pewne zaletystruct
- • typ jest zadeklarowany raz, • rozmiar jest automatycznie poprawny, • intencja kodu staje się jaśniejsza, • a kod jest łatwiejszy w utrzymaniu - ale tracisz ◦ ścisłe bezpieczeństwo typów, ◦ możliwość kopiowania i zwracania wartości typu oraz ◦ możliwość późniejszego dodawania członków bez niszczenia reszty kodu. Dwietypedef
s dla gołych tablic danego typu dają różne typy tylko wtedy, gdy mają różne rozmiary. Co więcej, jeśli użyjesztypedef
bez*
w argumencie funkcji, jest to równoważne zchar *
drastycznym zmniejszeniem bezpieczeństwa typów.Podsumowując :
typedef struct A_s_s { char m[113]; } A_s_t; // Full type safey, assignable typedef char A_c_t[113]; // Partial type-safety, not assignable A_s_t v_s(void); // Allowed A_c_t v_c(void); // Forbidden void s__v(A_s_t); // Type-safe, pass by value void sP_v(A_s_t *); // Type-safe void c__v(A_c_t); // UNSAFE, just means char * (GRRR!) void cP_v(A_c_t *); // SEMI-safe, accepts any array of 113
źródło
Struktura może zawierać funkcje inicjalizacji tablicy, kopiowania i fini emulujące niektóre zalety paradygmatów zarządzania pamięcią OOP. W rzeczywistości bardzo łatwo jest rozszerzyć tę koncepcję, aby napisać ogólne narzędzie do zarządzania pamięcią (używając struktury sizeof (), aby dokładnie wiedzieć, ile bajtów jest zarządzanych) w celu zarządzania dowolną strukturą zdefiniowaną przez użytkownika. Wiele inteligentnych baz kodu produkcyjnego napisanych w C używa ich intensywnie i zazwyczaj nigdy nie używa tablic, chyba że ich zakres jest bardzo lokalny.
W rzeczywistości w przypadku tablicy osadzonej w strukturze można wykonać inne „inteligentne rzeczy”, takie jak sprawdzanie powiązań w dowolnym momencie, gdy chciał się uzyskać dostęp do tej tablicy. Ponownie, chyba że zasięg tablicy jest bardzo ograniczony, używanie go i przekazywanie informacji między programami jest złym pomysłem. Wcześniej czy później napotkasz błędy, które nie pozwolą ci zasnąć w nocy i zrujnują twoje weekendy.
źródło
struct
zawierającej tylko tablicę.