Зачем объявлять структуру, которая содержит только массив в C? - PullRequest
128 голосов
/ 06 августа 2011

Я столкнулся с кодом, содержащим следующее:

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

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

Ответы [ 7 ]

182 голосов
/ 06 августа 2011

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

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

82 голосов
/ 06 августа 2011

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

typedef char ABC[MAX];

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

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

45 голосов
/ 06 августа 2011

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

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

26 голосов
/ 06 августа 2011

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

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

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

11 голосов
/ 06 августа 2011

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

struct String {
    char Char[MAX];
};

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

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

2 голосов
/ 16 августа 2015

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

Если вы не переносите массив в struct, вывсе еще может объявить typedef для этого: у этого есть некоторые преимущества struct - • тип объявляется один раз, • размер автоматически корректен, • цель кода становится более ясной, • и код более удобен в обслуживании- но вы теряете ◦ строгую безопасность типов, ability возможность копировать и возвращать значения типа и ◦ возможность добавлять элементы позже, не нарушая остальную часть вашего кода.Два 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
1 голос
/ 04 февраля 2014

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...