Возможный дубликат:
Разница между структурой и союзом в C
Я мог понять, что означает структура. Но я немного смущен различием между union и struct. Союз похож на долю памяти. Что именно это означает.?
Возможный дубликат:
Разница между структурой и союзом в C
Я мог понять, что означает структура. Но я немного смущен различием между union и struct. Союз похож на долю памяти. Что именно это означает.?
С объединением все члены имеют одну и ту же память. С помощью структуры они не обмениваются памятью, поэтому каждому члену структуры выделяется другое пространство в памяти.
Например:
union foo
{
int x;
int y;
};
foo f;
f.x = 10;
printf("%d\n", f.y);
Здесь мы присваиваем значение от 10 до foo::x
. Затем выводится значение foo::y
, которое также равно 10, так как x и y имеют одну и ту же память. Обратите внимание, что поскольку все члены профсоюза имеют одну и ту же память, компилятор должен выделить достаточное количество памяти для соответствия самому большому члену союза. Таким образом, объединение, содержащее char
и a long
, нуждается в достаточном пространстве для соответствия long
.
Но если мы используем struct:
struct foo
{
int x;
int y;
};
foo f;
f.x = 10;
f.y = 20;
printf("%d %d\n", f.x, f.y);
Мы присваиваем от 10 до x и от 20 до y, а затем печатаем их оба. Мы видим, что x равно 10, а y равно 20, потому что x и y не используют одну и ту же память.
EDIT: Также обратите внимание на комментарий Gman выше. Пример, который я предоставил союзу, предназначен только для демонстрационных целей. На практике вам не следует писать одному члену данных союза, а затем обращаться к другому члену данных. Обычно это просто заставляет компилятор интерпретировать битовый шаблон как другой тип, но вы можете получить неожиданные результаты, так как это undefined поведение.
Я использовал союзы для преобразования байтов в другие типы и из них. Я нахожу это проще, чем бит-сдвиг.
union intConverter {
int intValue;
struct {
byte hi;
byte lo;
} byteValue;
}
intConverter cv;
cv.intValue =1100;
printf("%X %X\n", cv.byteValue.hi, cv.byteValue.lo);
Где int 16-бит (был использован на микроконтроллере).
Каждый член профсоюза имеет одну и ту же память. Это означает, что если вы измените его, вы измените остальные. И если члены имеют разные типы, это может иметь непредсказуемые результаты. (не совсем непредсказуемый, но трудно предсказать, если вы не знаете о базовых моделях бит, которые составляют члены данных).
Возможно, более полезно иметь непредусмотренный пример того, для чего это полезно. (Я говорю "безусловный", потому что большинство бит-бейсбольных применений союза чрезвычайно вероломны. Бит-биение профсоюзов, взятых из бит-endian в малоэтажное оборудование, ломается наиболее (изначально) мистифицирующими способами.) (Конечно, я чтобы разрывать числа чисел с плавающей запятой, чтобы реализовать математические функции с порядковыми значениями быстрее, чем библиотека. Я просто добавляю утверждения о том, какие члены должны иметь одинаковые адреса.)
struct option1 { int type; /* other members */ }; struct option2 { int type; /* other members */ }; struct option3 { int type; /* other members */ }; union combo { int type; // guaranteed to exactly overlap with the structs' ints type. struct option1; struct option2; struct option3; }; // ... void foo(union combo *in) { switch(in.type) { case 1: { struct option1 *bar = in; //then process an option1 type of request } case 2: { struct option2 *bar = in; //then process an option2 type of request } case 3: { struct option3 *bar = in; //then process an option3 type of request } }
Такая конструкция очень распространена в X-программировании и в других ситуациях, когда вы хотите создать функцию, которая может принимать множество различных типов сообщений (с разными требованиями к аргументам и макетам).
Я предполагаю, что один из способов, которым вы можете думать о союзе, состоит в том, что он представляет собой набор псевдонимов различного типа для блока памяти, где каждый член объединения является "псевдонимом" с заданным типом. Каждый псевдоним относится к одному и тому же адресу в памяти. Как интерпретируются биты в этом адресе, определяется типом псевдонима.
Количество памяти, которую занимает объединение, всегда равно или, возможно, больше, чем размерный член объединения (из-за ограничений выравнивания).
Запустите эту программу и найдите выход.
#include < stdio.h >
int main() { union _testUnion { long long x; long long y; } testUnion; struct _testStruct { long long x; long long y; }testStruct; printf("Sizeof Union %d\n",sizeof(testUnion)); printf("Sizeof Struct %d\n",sizeof(testStruct)); return; }
Вы обнаружите, что размер структуры двойной, чем размер объединения. Это потому, что союз выделил пространство только для одной переменной, а struct выделил для двух.
Большинство ответов здесь верны. Объединение - это, по сути, способ доступа к тем же данным по-разному (например, вы можете получить доступ/интерпретировать 4 байта памяти в виде 1 целых чисел или 4 символа). Структуры, как вы знаете, являются простыми - набор разных, отдельных объектов с собственной памятью.
Обычно вам требуется Unions на более позднем этапе программирования по сравнению с Structs.