Разница между структурой и союзом

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

Решение

При использовании объединения вы должны использовать только один из элементов, потому что все они хранятся в одном месте. Это делает его полезным, когда вы хотите хранить что-то, что может быть одним из нескольких типов. С другой стороны, struct имеет отдельную область памяти для каждого из своих элементов, и все они могут быть использованы одновременно.

Чтобы привести конкретный пример их использования, некоторое время назад я работал над интерпретатором языка Scheme и по сути накладывал типы данных Scheme на типы данных языка C. Это включало хранение в struct перечисления, указывающего тип значения, и объединения для хранения этого значения.

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

редактирование: Если вам интересно, что установка x.b в 'c' изменяет значение x.a, то технически это не определено. На большинстве современных машин char - это 1 байт, а int - 4 байта, поэтому придание x.b значения 'c' приводит к тому, что первый байт x.a принимает то же значение:

union foo x;
x.a = 3;
x.b = 'c';
printf("%i, %i\n", x.a, x.b);

печатает

99, 99

Почему эти два значения одинаковы? Потому что последние 3 байта int 3 все нулевые, поэтому оно читается как 99. Если мы подставим большее число для x.a, вы увидите, что это не всегда так:

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.

BUT

В C порядок байтов в int не определен. Эта программа перезаписала 0xEF на 0x22 на моем Mac, но есть и другие платформы, где вместо него будет перезаписан 0xDE, потому что порядок байтов, составляющих int, обратный. Поэтому при написании программы никогда не следует полагаться на поведение перезаписи определенных данных в объединении, поскольку оно не переносимо.

Для получения дополнительной информации об упорядочивании байтов ознакомьтесь с endianness.

Комментарии (12)

Здесь'ы короткий ответ: структуры представляет собой запись структуры: каждый элемент структуры выделяет новые пространства. Так, структуры, как

struct foobarbazquux_t {
    int foo;
    long bar;
    double baz; 
    long double quux;
}

выделяет по крайней мере (оператор sizeof(тип int)+оператор sizeof(длинный)+оператор sizeof(двойная)+размер(двойной)) байт в памяти для каждого экземпляра. (с"как минимум" и потому что архитектура ограничений расклад может заставить компилятор колодки структуры.)

С другой стороны,

union foobarbazquux_u {
    int foo;
    long bar;
    double baz; 
    long double quux;
}

выделяет кусок памяти и дает ему четыре псевдонимы. Так как sizeof(Союз foobarbazquux_u) ≥ максимум((как sizeof(тип int),размер(длинная),размер(двойной),размер(двойной)), опять же с возможностью того, для выравнивания.

Комментарии (0)

Есть ли какие-хорошим примером, чтобы дать разницу между 'структура' и 'Союз'?

Воображаемый протокол связи

struct packetheader {
   int sourceaddress;
   int destaddress;
   int messagetype;
   union request {
       char fourcc[4];
       int requestnumber;
   };
};

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

Профсоюзы преимущественно низкого уровня детализации основана на C'наследие, как язык системного программирования, куда "перекрытие" в местах хранения применяются иногда в эту сторону. Иногда вы можете использовать союзы для сохранения памяти, где у вас есть структура данных, в которой только один из нескольких типов будут сохранены в одно время.

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

Комментарии (3)

Как вы уже в своем вопросе, основное различие между Союзом и структура, что союз членов наложение памяти друг друга, так что значение sizeof Союза-это одно , а структуры членов выкладываются один за другим (с дополнительной прокладкой между ними). Также Союз является достаточно большим, чтобы содержать всех своих членов, и у трассы, подходит для всех ее членов. Так давайте'ы сказать, типа int может храниться только в 2 байта адреса, а 2 байта, и долго могут храниться только в 4 адресов байта и 4 байта. Следующий Союз

union test {
    int a;
    long b;
}; 

может иметь размер от 4, и требование согласования 4. Как Union и struct может иметь заполнение в конце, а не в их начале. Пишу структуру, меняется только значение элемента записи. Запись в члены Союза будут отображаться ценность всех других поврежденных членов. Вы не можете получить к ним доступ, если вы еще'т написанные им прежде, в противном случае поведение неопределено. НКУ предусматривает как расширение, которое вы можете на самом деле читать от членов союза, даже если вы еще'т написанные им совсем недавно. Для операционной системы, это не'т иметь дело с программой пользователь пишет в союз или к структуре. На самом деле это только проблема компилятора.

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

struct test {
    int a;
    double b;
} * some_test_pointer;

some_test_pointer можете указывать в int* и Double*. Если вы разыгрываете адрес тест тип в int*, это будет указывать на его первый член, "а", на самом деле. То же самое верно и для Союза. Таким образом, потому что союз всегда будет иметь правильное выравнивание, можно использовать союз, чтобы указывающую на некоторый тип действует:

union a {
    int a;
    double b;
};

Этот союз будет на самом деле быть в состоянии указывать на int, и двойной:

union a * v = (union a*)some_int_pointer;
*some_int_pointer = 5;
v->a = 10;
return *some_int_pointer;    

на самом деле действительно, как заявил стандарта C99:

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

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

Компилятор выиграл'т оптимизации в организации в->а = 10; так как это может повлиять на стоимость *some_int_pointer (и функция вернет 10 вместо 5).

Комментарии (2)

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

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

#include                                                                                                                                        

union foo {
    struct float_guts {
        unsigned int fraction : 23;
        unsigned int exponent : 8;
        unsigned int sign     : 1;
    } fg;
    float f;
};

void print_float(float f) {
    union foo ff;
    ff.f = f;
    printf("%f: %d 0x%X 0x%X\n", f, ff.fg.sign, ff.fg.exponent, ff.fg.fraction);

}

int main(){
    print_float(0.15625);
    return 0;
}

Взгляните на один точность Описание На Википедии. Я использовал пример и магическое число 0.15625 оттуда.


"союз" также может быть использован для реализации алгебраического типа данных, который имеет несколько альтернатив. Я нашел пример, что в "ьquot реальный мир Хаскелл&; книга О'Салливан, Стюарт, и Goerzen. Проверьте это в размеченном объединении раздел.

Ура!

Комментарии (0)

Не с технической точки зрения означает :

Предположение: стул = блок памяти , люди = переменная

Конструкция : Если есть 3 человека, они могут сесть в кресло своих размеров соответственно .

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

С технической точки зрения означает :

Указанные ниже программы дает глубокое погружение в структуру и Союза .

struct MAIN_STRUCT
{
UINT64 bufferaddr;   
union {
    UINT32 data;
    struct INNER_STRUCT{
        UINT16 length;  
        UINT8 cso;  
        UINT8 cmd;  
           } flags;
     } data1;
};

Общая MAIN_STRUCT размер =оператор sizeof(тип uint64) для bufferaddr + оператор sizeof(UNIT32) для Союза + 32 бит для заполнения(в зависимости от архитектуры процессора) = 128 бит . По структуре все участники получают блок памяти непрерывно .

Союз получает один блок памяти члена максимальный размер(здесь ее 32 бит) . Внутри Союза еще одна структура лжи(INNER_STRUCT) ее члены получат блока памяти общим размером 32 бита(16+8+8) . В союзе либо INNER_STRUCT(32 бит) член или данных(32 бит) могут быть доступны .

Комментарии (1)

"union" и "struct" - это конструкции языка Си. Говорить о разнице между ними на уровне ОС неуместно, поскольку именно компилятор выдает разный код при использовании того или иного ключевого слова.

Комментарии (0)

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

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

union SIGSELECT
{
  SIGNAL_1 signal1;
  SIGNAL_2 signal2;
  .....
};

В этом случае, процесс использовать только высокого памяти всех сигналов. но если вы используете struct в этом случае, использование памяти будет сумма всех сигналов. Большая разница.

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

Комментарии (0)

У вас есть то, что's все. А так, в принципе, что'с точки союзов?

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

Почему это важно? Не реально для космических завоеваний. Да, вы можете получить некоторые биты или сделать небольшой отступ, но это's не главное больше.

Это's для типа безопасности, это позволяет сделать какой-то 'динамическая типизация': компилятор знает, что ваш контент могут иметь различное значение и точный смысл, как интерпретировать это до вас, во время выполнения. Если у вас есть указатель, который может указывать на различные типы, вы должны использовать соединение, в противном случае ваш код может быть неправильным из-за сглаживания проблем (компилятор говорит себе "О, только этот указатель может указывать на этого типа, так что я могу оптимизировать эти доступы...", и плохие вещи могут случиться).

Комментарии (0)

Структура выделяет общий размер всех элементов в ней.

Объединение выделяет только столько памяти, сколько требуется его самому большому члену.

Комментарии (1)

в чем разница между структурой и Союза?

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

struct s_tag
{
   int a; 
   long int b;
} x;

union u_tag
{
   int a; 
   long int b;
} y;

Здесь есть два члена внутри структуры struct и Union: int и Long инт. Пространство памяти для int это 4 байта, и в памяти надолго int-это: 8 в 32-битной операционной системы.

Поэтому для структуры 4+8=12 байт будет создан во время 8 байт будут созданы для Союза

Пример кода:

#include
struct s_tag
{
  int a;
  long int b;
} x;
union u_tag
{
     int a;
     long int b;
} y;
int main()
{
    printf("Memory allocation for structure = %d", sizeof(x));
    printf("\nMemory allocation for union = %d", sizeof(y));
    return 0;
}

Реф:http://ВСП.codingpractise.ком/дома/с-Программирование/структурно-Союз/

Комментарии (0)

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

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

struct emp
{
    char x;//1 byte
    float y; //4 byte
} e;

общий объем памяти это сделать =>5 байт

union emp
{
    char x;//1 byte
    float y; //4 byte
} e;

общая память это сделать =4 байта

Комментарии (0)

Использование Союза Союзы часто используются, когда требуется специализированная разговоры типа. Чтобы получить представление о полезности Союза. Си стандартная библиотека/C определяет никакой функции, специально предназначенные для создания коротких целых чисел в файл. Используя fwrite() encurs несет чрезмерную нагрузку для простой операции. Однако с помощью союза вы можете легко создать функцию, которая пишет в двоичном виде короткого целого числа в один файл байт за раз. Я предполагаю, что короткие целые числа 2 байт

ПРИМЕР:

#include
union pw {
short int i;
char ch[2];
};
int putw(short int num, FILE *fp);
int main (void)
{
FILE *fp;
fp fopen("test.tmp", "wb ");
putw(1000, fp); /* write the value 1000 as an integer*/
fclose(fp);
return 0;
}
int putw(short int num, FILE *fp)
{
pw word;
word.i = num;
putc(word.c[0] , fp);
return putc(word.c[1] , fp);
}    

хотя putw() я позвонила с коротким целым числом, это можно использовать putc() и fwrite(). Но я хотел показать пример dominstrate, как союз может быть использована

Комментарии (0)

Профсоюзы пригодиться при написании байтов функция которых приведен ниже. Это's не возможный с структуры.

int main(int argc, char **argv) {
    union {
        short   s;
        char    c[sizeof(short)];
    } un;

    un.s = 0x0102;

    if (sizeof(short) == 2) {
        if (un.c[0] == 1 && un.c[1] == 2)
            printf("big-endian\n");
        else if (un.c[0] == 2 && un.c[1] == 1)
            printf("little-endian\n");
        else
            printf("unknown\n");
    } else
        printf("sizeof(short) = %d\n", sizeof(short));

    exit(0);
}
// Program from Unix Network Programming Vol. 1 by Stevens.
Комментарии (0)

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

Комментарии (0)