Відповіді:
Це дозволяє передати масив функції за значенням або повернути його за значенням з функції.
Структури можуть передаватися за значенням, на відміну від масивів, які розпадаються на покажчик у цих контекстах.
Ще одна перевага полягає в тому, що він скорочує розмір, тому вам не доведеться використовувати [MAX]
весь код, де б ви не оголошували такий об'єкт. Цього можна досягти і за допомогою
typedef char ABC[MAX];
але тоді у вас є набагато більша проблема: ви повинні знати, що ABC
це тип масиву (навіть якщо ви цього не можете бачити, коли ви оголошуєте змінні типу ABC
), інакше ви будете вражені тим фактом, що ABC
означатиме щось інше у списку аргументів функції проти декларації / визначення змінної.
Ще одна перевага полягає в тому, що структура дозволяє вам згодом додавати більше елементів, якщо вам потрібно, без необхідності переписувати багато коду.
Ви можете скопіювати це так.
struct ABC a, b;
........
a = b;
Для масиву вам потрібно буде використовувати функцію memcpy або цикл, щоб призначити кожен елемент.
Ви можете використовувати struct для створення нового типу даних, наприклад рядка . Ви можете визначити:
struct String {
char Char[MAX];
};
або ви можете створити Список даних, який ви можете використовувати їх аргументом функцій або повернути їх у ваші методи. Структура є більш гнучкою, ніж масив, тому що вона може підтримувати деякі оператори типу = і ви можете визначити в ній деякі методи.
Сподіваюся, це вам корисно :)
Ще одна перевага використання такого типу struct
полягає в тому, що він застосовує безпеку типу, де б таке struct
не використовувалося; особливо якщо у вас є два типи, що складаються з масивів однакового розміру, які використовуються для різних цілей, ці типи допоможуть вам уникнути випадкового використання масиву неналежним чином.
Якщо ви не загортаєте масив у a struct
, ви все одно можете оголосити typedef
для нього: це має деякі переваги: struct
- тип оголошується один раз, • розмір автоматично правильний, • намір коду стає зрозумілішим, • і код є більш ретельним - але ви втрачаєте ◦ сувору безпеку типу, ◦ можливість копіювати та повертати значення типу та ◦ можливість додавати членів пізніше, не порушуючи решту вашого коду. Два typedef
s для оголених масивів даного типу дають різні типи, лише якщо вони різної величини. Крім того, якщо ви використовуєте typedef
НЕ *
в якості аргументу функції, що еквівалентно char *
, різко знижуючи безпеку типів.
Підсумовуючи :
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
Структура може містити функції ініціалізації масиву, копіювання та функції fini, що імітують деякі переваги парадигм управління пам'яттю OOP. Насправді, дуже просто розширити цю концепцію, щоб написати загальну утиліту управління пам’яттю (за допомогою структури sizeof (), щоб точно знати, скільки байтів керується) для управління будь-якою визначеною користувачем структурою. Багато баз інтелектуальних виробничих кодів, написаних на C, використовують їх дуже часто і, як правило, ніколи не використовують масив, якщо його сфера дії не є дуже локальною.
Насправді для масиву, вбудованого в структуру, ви можете робити інші "розумні речі", такі як прив'язка перевірки будь-коли, коли ви хочете отримати доступ до цього масиву. Знову ж таки, якщо область застосування масиву дуже обмежена, погано використовувати її і передавати інформацію по програмах. Рано чи пізно ви зіткнетеся з помилками, які триматимуть вас неспати вночі та зіпсують вихідні.
struct
містить, що містить лише масив.