Зачем объявлять структуру, содержащую только массив в C?

Нашел код, содержащий следующее:

struct ABC {
    unsigned long array[MAX];
} abc;

Когда имеет смысл использовать такое объявление?

Ответ 1

Он позволяет передавать массив функции по значению или возвращать значение из функции.

Структуры могут передаваться по значению, в отличие от массивов, которые распадаются на указатель в этих контекстах.

Ответ 2

Другим преимуществом является то, что он абстрагирует размер, поэтому вам не нужно использовать [MAX] по всему вашему коду везде, где вы объявляете такой объект. Это также может быть достигнуто с помощью

typedef char ABC[MAX];

но тогда у вас есть гораздо большая проблема: вы должны знать, что ABC - это тип массива (даже если вы не видите этого, когда объявляете переменные типа ABC), иначе вы получите что ABC будет означать что-то другое в списке аргументов функции по сравнению с объявлением/определением переменной.

Еще одно преимущество заключается в том, что структура позволяет вам позже добавлять дополнительные элементы, если вам нужно, без необходимости переписывать много кода.

Ответ 3

Вы можете скопировать структуру и вернуть структуру из функции.

Вы не можете сделать это с помощью массива - если он не является частью структуры!

Ответ 4

Вы можете скопировать его вот так.

struct ABC a, b;
........
a = b;

Для массива вам нужно будет использовать функцию memcpy или цикл для назначения каждого элемента.

Ответ 5

Вы можете использовать struct для создания нового типа данных, например string. вы можете определить:

struct String {
    char Char[MAX];
};

или вы можете создать Список данных, которые вы можете использовать с помощью аргументов функций или вернуть их в свои методы. Структура более гибкая, чем массив, поскольку она может поддерживать некоторые операторы типа =, и вы можете определить некоторые методы в ней.

Надеюсь, это полезно для вас:)

Ответ 6

Структура может содержать инициализацию массива, функции копирования и fini, эмулирующие некоторые из преимуществ парадигм управления памятью OOP. На самом деле, очень просто расширить эту концепцию, чтобы написать универсальную утилиту управления памятью (используя структуру sizeof(), чтобы точно знать, сколько байтов управляется) для управления любой определяемой пользователем структурой. Многие из базовых кодов интеллектуального производственного кода, написанные на C, используют их в значительной степени и обычно никогда не используют массив, если его область не является очень локальной.

Фактически для массива, встроенного в структуру, вы можете делать другие "умные вещи", такие как привязка проверки в любое время, когда вы хотите получить доступ к этому массиву. Опять же, если область массива очень ограничена, это плохая идея использовать ее и передавать информацию через программы. Рано или поздно вы столкнетесь с ошибками, которые помогут вам проснуться по ночам и погубить ваши выходные.

Ответ 7

Другим преимуществом использования 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