Есть ли хороший пример, чтобы дать разницу между а struct
и а union
? В основном я знаю, что struct
использует всю память своего члена и union
использует наибольшее пространство памяти членов. Есть ли другая разница в уровне ОС?
С объединением вы должны использовать только один из элементов, потому что все они хранятся в одном месте. Это делает его полезным, когда вы хотите сохранить что-то, что может быть одного из нескольких типов. Структура, с другой стороны, имеет отдельную ячейку памяти для каждого из своих элементов, и все они могут использоваться одновременно.
Чтобы привести конкретный пример их использования, я некоторое время назад работал над интерпретатором Scheme и по существу накладывал типы данных Scheme на типы данных C. Это включало сохранение в структуре перечисления, указывающего тип значения и объединение для хранения этого значения.
union foo {
int a; // can't use both a and b at once
char b;
} foo;
struct bar {
int a; // can use both a and b simultaneously
char b;
} bar;
union foo x;
x.a = 3; // OK
x.b = 'c'; // NO! this affects the value of x.a!
struct bar y;
y.a = 3; // OK
y.b = 'c'; // OK
редактировать: если вам интересно, какой параметр xb для 'c' меняет значение xa на, технически говоря, он не определен. На большинстве современных машин char равен 1 байту, а int равен 4 байта, поэтому, давая xb значение 'c', вы получаете первый байт xa того же значения:
union foo x;
x.a = 3;
x.b = 'c';
printf("%i, %i\n", x.a, x.b);
печать
99, 99
Почему эти два значения одинаковы? Поскольку последние 3 байта int 3 равны нулю, поэтому он также читается как 99. Если мы введем большее число для xa, вы увидите, что это не всегда так:
union foo x;
x.a = 387439;
x.b = 'c';
printf("%i, %i\n", x.a, x.b);
печать
387427, 99
Чтобы ближе познакомиться с фактическими значениями памяти, давайте установим и распечатаем значения в шестнадцатеричном виде:
union foo x;
x.a = 0xDEADBEEF;
x.b = 0x22;
printf("%x, %x\n", x.a, x.b);
печать
deadbe22, 22
Вы можете ясно видеть, где 0x22 переписал 0xEF.
НО
В C порядок байтов в int не определен. Эта программа перезаписала 0xEF с 0x22 на моем Mac, но есть другие платформы, где вместо этого перезаписывается 0xDE, потому что порядок байтов, составляющих int, был обратным. Поэтому при написании программы вы никогда не должны полагаться на поведение перезаписи определенных данных в объединении, потому что оно не переносимо.
Для получения дополнительной информации о порядке байтов, проверьте порядок байтов .
Вот краткий ответ: структура - это структура записи: каждый элемент в структуре выделяет новое пространство. Итак, структура как
выделяет как минимум
(sizeof(int)+sizeof(long)+sizeof(double)+sizeof(long double))
байты в памяти для каждого экземпляра. («По крайней мере», потому что ограничения выравнивания архитектуры могут заставить компилятор дополнить структуру.)С другой стороны,
выделяет один кусок памяти и дает ему четыре псевдонима. Итак
sizeof(union foobarbazquux_u) ≥ max((sizeof(int),sizeof(long),sizeof(double),sizeof(long double))
, еще раз с возможностью некоторого дополнения для выравнивания.источник
Воображаемый протокол связи
В этом воображаемом протоколе было определено, что на основе «типа сообщения» следующее расположение в заголовке будет либо номером запроса, либо четырехзначным кодом, но не обоими. Короче говоря, объединения позволяют одному и тому же месту хранения представлять более одного типа данных, при этом гарантируется, что вы захотите хранить только один из типов данных одновременно.
Союзы - это в основном детали низкого уровня, основанные на наследии C как языка системного программирования, где таким образом иногда используются «перекрывающиеся» места хранения. Иногда вы можете использовать объединения для сохранения памяти, где у вас есть структура данных, в которой одновременно может быть сохранен только один из нескольких типов.
В общем, ОС не заботится и не знает о структурах и союзах - они оба для нее просто блоки памяти. Структура - это блок памяти, в котором хранятся несколько объектов данных, где эти объекты не перекрываются. Объединение - это блок памяти, в котором хранится несколько объектов данных, но в котором хранится только самый большой из них, и, таким образом, одновременно может храниться только один из объектов данных.
источник
packetheader ph;
как получить доступ к requestnumber?ph.request.requestnumber
?Как вы уже заявили в своем вопросе, основное различие между
union
иstruct
заключается в том, чтоunion
члены накладываются друг на друга в памяти, так что размер объединения равен единице, аstruct
члены располагаются один за другим (с дополнительным заполнением между ними). Кроме того, профсоюз достаточно большой, чтобы вместить всех его членов, и иметь выравнивание, подходящее всем его членам. Допустим,int
можно хранить только по 2-байтовым адресам и иметь ширину 2 байта, а long можно хранить только по 4-байтовым адресам и иметь длину 4 байта. Следующий союзможет иметь значение
sizeof
4 и требование выравнивания 4. И объединение, и структура могут иметь заполнение в конце, но не в начале. Запись в структуру изменяет только значение записанного члена. Письмо члену профсоюза сделает значение всех остальных членов недействительным. Вы не можете получить к ним доступ, если ранее не писали, иначе поведение не определено. GCC предоставляет в качестве расширения, которое вы на самом деле можете прочитать от членов профсоюза, даже если вы не писали им последнее время. Для операционной системы не должно иметь значения, записывает ли пользовательская программа в объединение или в структуру. На самом деле это только проблема компилятора.Другим важным свойством union и struct является то, что они позволяют указателю на них указывать на типы любого из его членов . Таким образом, следующее действительно:
some_test_pointer может указывать на
int*
илиdouble*
. Если вы приведете адрес типаtest
кint*
, он наa
самом деле будет указывать на своего первого члена . То же самое верно и для союза. Таким образом, поскольку объединение всегда будет иметь правильное выравнивание, вы можете использовать объединение, чтобы сделать указание на некоторый тип допустимым:Этот союз на самом деле сможет указывать на int и double:
действительно действует, как указано в стандарте C99:
Компилятор не будет оптимизировать,
v->a = 10;
поскольку это может повлиять на значение*some_int_pointer
(и функция вернется10
вместо5
).источник
А
union
полезно в паре сценариев.union
может быть инструментом для манипуляций очень низкого уровня, таких как написание драйверов устройств для ядра.Пример , который рассечение
float
номера с помощьюunion
оператора Аstruct
с битовыми полями и аfloat
. Я сохраняю число вfloat
, и позже я могу получить доступ к определенным частямfloat
через негоstruct
. В примере показано, какunion
использовать разные углы для просмотра данных.Взгляните на описание с одинарной точностью в Википедии. Я использовал пример и магическое число 0,15625 оттуда.
union
также может использоваться для реализации алгебраического типа данных, который имеет несколько альтернатив. Я нашел пример этого в книге О'Салливана, Стюарта и Гёрзена "Реальный мир Хаскелла". Проверьте это в разделе «Дискриминационный союз ».Ура!
источник
« union » и « struct » являются конструкциями языка C. Говорить о разнице в «уровне ОС» между ними неуместно, поскольку компилятор создает другой код, если вы используете то или иное ключевое слово.
источник
Не говоря технически означает:
Предположение: стул = блок памяти, люди = переменные
Структура : если есть 3 человека, они могут сидеть в кресле их размера соответственно.
Союз : если есть 3 человека , то там будет сидеть только один стул, все должны использовать один и тот же стул, когда они хотят сидеть.
Технически говоря означает:
Нижеприведенная программа дает глубокое представление о структуре и объединении.
Общий размер MAIN_STRUCT = sizeof (UINT64) для bufferaddr + sizeof (UNIT32) для объединения + 32 бита для заполнения (зависит от архитектуры процессора) = 128 бит. Для структуры все члены получают блок памяти непрерывно.
Union получает один блок памяти элемента максимального размера (здесь его 32-битный). Внутри объединения лежит еще одна структура (INNER_STRUCT), члены которой получают блок памяти размером 32 бита (16 + 8 + 8). В объединении могут быть доступны либо член INNER_STRUCT (32 бита), либо данные (32 бита).
источник
Да, основное различие между struct и union такое же, как вы заявили. Struct использует всю память своего члена, а union использует самое большое пространство памяти членов.
Но вся разница заключается в необходимости использования памяти. Лучшее использование объединения можно увидеть в процессах Unix, где мы используем сигналы. как процесс может воздействовать только на один сигнал одновременно. Таким образом, общая декларация будет:
В этом случае процесс использует только самую высокую память из всех сигналов. но если вы используете struct в этом случае, использование памяти будет суммой всех сигналов. Делает много различий.
Подводя итог, следует выбрать Union, если вы знаете, что у вас есть доступ к одному из участников одновременно.
источник
У вас это есть, вот и все. Но так, в принципе, какой смысл в профсоюзах?
Вы можете разместить в одном месте контент разных типов. Вы должны знать тип того, что вы сохранили в объединении (так часто вы помещаете это в
struct
тег типа ...).Почему это важно? Не совсем для космической выгоды. Да, вы можете получить некоторые биты или сделать некоторые отступы, но это уже не главное.
Это для безопасности типов, это позволяет вам выполнять какую-то «динамическую типизацию»: компилятор знает, что ваш контент может иметь разные значения и точное значение того, как вы его интерпретируете, во время выполнения. Если у вас есть указатель, который может указывать на разные типы, вы ДОЛЖНЫ использовать объединение, в противном случае ваш код может быть неправильным из-за проблем с наложением имен (компилятор говорит себе: «О, только этот указатель может указывать на этот тип, поэтому я могу оптимизировать»). из тех доступов ... ", и плохие вещи могут случиться).
источник
Структура распределяет общий размер всех элементов в ней.
Объединение только выделяет столько памяти, сколько требует его самый большой член.
источник
В чем разница между структурой и объединением?
Краткий ответ: почтение в распределении памяти. Объяснение: В структуре будет создано пространство памяти для всех элементов внутри структуры. В объединенном пространстве памяти будет создано только для члена, который нуждается в наибольшем объеме памяти. Рассмотрим следующий код:
Здесь есть два члена внутри struct и union: int и long int. Объем памяти для int составляет 4 байта, а объем памяти для длинных int составляет 8 в 32-разрядной операционной системе.
Таким образом, для структуры 4 + 8 = 12 байтов будет создано в то время как 8 байтов будут созданы для объединения
Пример кода:
Ссылка: http://www.codingpractise.com/home/c-programming/structure-and-union/
источник
Использование профсоюзов часто используется, когда требуются специализированные разговоры. Чтобы получить представление о полезности объединения. Стандартная библиотека c / c не определяет функции, специально предназначенные для записи коротких целых чисел в файл. Использование fwrite () влечет за собой чрезмерные накладные расходы для простой операции. Однако, используя объединение, вы можете легко создать функцию, которая записывает двоичный файл с коротким целым числом в файл по одному байту за раз. Я предполагаю, что короткие целые числа имеют длину 2 байта
ПРИМЕР:
хотя putw () я вызывал с коротким целым числом, было возможно использовать putc () и fwrite (). Но я хотел показать пример, чтобы доминировать, как профсоюз может быть использован
источник
структура представляет собой набор данных различного типа, в котором могут находиться разные типы данных, и каждый получает свой блок памяти
мы обычно использовали объединение, когда мы уверены, что только одна переменная будет использоваться одновременно, и вы хотите полностью использовать существующую память, потому что она получает только один блок памяти, который равен наибольшему типу.
общий объем памяти = 5 байт
общий объем памяти = 4 байта
источник
Союзы пригодятся при написании функции упорядочения байтов, которая приведена ниже. Это невозможно с помощью структур.
источник
Объединение отличается от структуры, так как объединение повторяется над остальными: оно переопределяет одну и ту же память, в то время как структура определяет одно за другим без наложений и переопределений.
источник