Natknąłem się na kod zawierający:
struct ABC {
unsigned long array[MAX];
} abc;
Kiedy stosowanie takiej deklaracji ma sens?
Odpowiedzi:
Umożliwia przekazanie tablicy do funkcji przez wartość lub pobranie jej przez wartość z funkcji.
Struktury mogą być przekazywane przez wartość, w przeciwieństwie do tablic, które w tych kontekstach rozpadają się na wskaźnik.
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 typu ABC
), inaczej zostaniesz ukąszony faktem, że ABC
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.
Możesz skopiować strukturę i zwrócić strukturę z funkcji.
Nie możesz tego zrobić z tablicą - chyba że jest częścią struktury!
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.
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 :)
Inną zaletą stosowania takiego znakustruct
jest to, że wymusza bezpieczeństwo typu wszędzie tam, gdzie taki struct
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 zalety struct
- • 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. Dwie typedef
s dla gołych tablic danego typu dają różne typy tylko wtedy, gdy mają różne rozmiary. Co więcej, jeśli użyjesz typedef
bez *
w argumencie funkcji, jest to równoważne z char *
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
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.
struct
zawierającej tylko tablicę.