Нашел код, содержащий следующее:
struct ABC {
unsigned long array[MAX];
} abc;
Когда имеет смысл использовать такое объявление?
Нашел код, содержащий следующее:
struct ABC {
unsigned long array[MAX];
} abc;
Когда имеет смысл использовать такое объявление?
Он позволяет передавать массив функции по значению или возвращать значение из функции.
Структуры могут передаваться по значению, в отличие от массивов, которые распадаются на указатель в этих контекстах.
Другим преимуществом является то, что он абстрагирует размер, поэтому вам не нужно использовать [MAX]
по всему вашему коду везде, где вы объявляете такой объект. Это также может быть достигнуто с помощью
typedef char ABC[MAX];
но тогда у вас есть гораздо большая проблема: вы должны знать, что ABC
- это тип массива (даже если вы не видите этого, когда объявляете переменные типа ABC
), иначе вы получите что ABC
будет означать что-то другое в списке аргументов функции по сравнению с объявлением/определением переменной.
Еще одно преимущество заключается в том, что структура позволяет вам позже добавлять дополнительные элементы, если вам нужно, без необходимости переписывать много кода.
Вы можете скопировать структуру и вернуть структуру из функции.
Вы не можете сделать это с помощью массива - если он не является частью структуры!
Вы можете скопировать его вот так.
struct ABC a, b;
........
a = b;
Для массива вам нужно будет использовать функцию memcpy или цикл для назначения каждого элемента.
Вы можете использовать struct для создания нового типа данных, например string. вы можете определить:
struct String {
char Char[MAX];
};
или вы можете создать Список данных, которые вы можете использовать с помощью аргументов функций или вернуть их в свои методы. Структура более гибкая, чем массив, поскольку она может поддерживать некоторые операторы типа =, и вы можете определить некоторые методы в ней.
Надеюсь, это полезно для вас:)
Структура может содержать инициализацию массива, функции копирования и fini, эмулирующие некоторые из преимуществ парадигм управления памятью OOP. На самом деле, очень просто расширить эту концепцию, чтобы написать универсальную утилиту управления памятью (используя структуру sizeof(), чтобы точно знать, сколько байтов управляется) для управления любой определяемой пользователем структурой. Многие из базовых кодов интеллектуального производственного кода, написанные на C, используют их в значительной степени и обычно никогда не используют массив, если его область не является очень локальной.
Фактически для массива, встроенного в структуру, вы можете делать другие "умные вещи", такие как привязка проверки в любое время, когда вы хотите получить доступ к этому массиву. Опять же, если область массива очень ограничена, это плохая идея использовать ее и передавать информацию через программы. Рано или поздно вы столкнетесь с ошибками, которые помогут вам проснуться по ночам и погубить ваши выходные.
Другим преимуществом использования struct
является то, что он обеспечивает безопасность типов везде, где используется struct
; особенно если у вас есть два типа, состоящие из массивов одинакового размера, используемых для разных целей, эти типы помогут вам избежать случайного использования массива ненадлежащим образом.
Если вы не завершите массив в struct
, вы можете объявить typedef
для него: это имеет некоторые преимущества struct
- • тип объявляется один раз, • размер автоматически исправляет, • цель кода становится яснее, • код более удобен в обслуживании, но вы теряете ◦ строгую безопасность типа, ◦ возможность копировать и возвращать значения типа и ◦ возможность добавлять участников позже, не нарушая покоя вашего кода. Два typedef
для голых массивов данного типа дают разные типы, если они имеют разные размеры. Более того, если вы используете 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