Когда использовать объединение и когда использовать структуру - PullRequest
5 голосов
/ 31 октября 2011

Я знаю разницу между объединением и структурой. Но с точки зрения дизайна и кодирования, каковы различные варианты использования объединения вместо структуры? Одним из них является космическая оптимизация. Есть ли еще преимущества в их использовании?

Ответы [ 4 ]

10 голосов
/ 31 октября 2011

На самом деле есть только два основных применения.Первое - создать дискриминационный союз.Это, вероятно, то, что вы думали о «оптимизации пространства», но есть кое-что еще к этому.Вам нужен дополнительный бит данных, чтобы узнать, какой член объединения является «живым» (содержит действительные данные), поскольку компилятор не делает этого за вас.Обычно вы видите такой код, имеющий объединение внутри структуры, что-то вроде:

struct mixed {
  enum { TYPE_INT, TYPE_FLOAT } type;
  union {
    int    int_value;
    float  float_value;
  } data;
};

При назначении либо data.int_value, либо data.float_value вы должны установить тип членак соответствующему значению перечисления.Тогда ваш код, использующий смешанное значение, может выяснить, следует ли читать int_value или float_value.

Вторым значительным применением союзов является предложение API, который позволяет пользователю обращаться к одним и тем же данным несколькими способами.Это довольно ограничено, поскольку требует, чтобы все типы в объединении были помещены в память одинаковыми способами.Например, int и float совершенно разные, и доступ к float в виде целого числа не дает вам особо значимых данных.

Для полезного примера этого варианта использования посмотрите, сколько сетевых API-интерфейсов определитобъединение для адресов IPv4, что-то вроде:

union ipv4addr {
  unsigned  address;
  char      octets[4];
};

Большая часть кода просто хочет передать 32-битное целочисленное значение, но некоторый код хочет прочитать отдельные октеты (байты).Это все выполнимо с приведением указателей, но это немного проще, более самодокументируется и, следовательно, немного безопаснее использовать объединение таким образом.

В общем, если вы не уверены, что вынужен союз, вам почти наверняка он не нужен.

5 голосов
/ 31 октября 2011

Вы используете объединение, когда ваша «вещь» может быть одной из множества разных вещей, но только по одной за раз.

Вы используете структуру, когда ваша «вещь» должна бытьгруппа других вещей.

Например, объединение может использоваться для представления виджетов или gizmos (с полем, позволяющим нам узнать, что это такое), что-то вроде:

struct {
    int isAGizmo;
    union {
        widget w;
        gizmo g;
    }
}

В этом примере w и g будут перекрываться в памяти.

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

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

struct {
    widget w;
    gizmo g;
}

В этом случае g будет находиться в другом месте памяти, где-то после w(без перекрытия).

Вариантов использования для этого предостаточно,например, структуры, содержащие макеты записей для вашего приложения телефонной книги, которые, несомненно, принесут вам миллиарды долларов в выбранном вами магазине приложений: -)

0 голосов
/ 31 октября 2011

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

Также объединения могут значительно упростить математику указателей при работе со сложнымипередача данных между компонентами.Например, при разработке компиляторов с LEX и YACC значения передаются от лексера парсеру в объединении.Реализация синтаксического анализатора и последующее приведение типов значительно упрощены благодаря использованию объединения.

0 голосов
/ 31 октября 2011

В некоторых случаях нам, возможно, придется использовать только одну переменную за раз, но разные результаты должны храниться под разными именами.В таких случаях объединение поможет, выделив одинаковое пространство для каждой переменной в одном месте с максимальным размером переменной.

, т.е. если мы используем int и char, то union будет выделять пространство для char, который имеет больший размер и intтоже будет храниться в том же пространстве, что и предыдущий.

...