Подтвердить что ты не робот

Какое основное различие между "союзом" и "структурой" в C.?

Возможный дубликат:
Разница между структурой и союзом в C

Я мог понять, что означает структура. Но я немного смущен различием между union и struct. Союз похож на долю памяти. Что именно это означает.?

4b9b3361

Ответ 1

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

Например:

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 поведение.

Ответ 2

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

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-бит (был использован на микроконтроллере).

Ответ 3

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

Ответ 4

Возможно, более полезно иметь непредусмотренный пример того, для чего это полезно. (Я говорю "безусловный", потому что большинство бит-бейсбольных применений союза чрезвычайно вероломны. Бит-биение профсоюзов, взятых из бит-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-программировании и в других ситуациях, когда вы хотите создать функцию, которая может принимать множество различных типов сообщений (с разными требованиями к аргументам и макетам).

Ответ 5

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

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

Ответ 6

Запустите эту программу и найдите выход.

#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 выделил для двух.

Ответ 7

Большинство ответов здесь верны. Объединение - это, по сути, способ доступа к тем же данным по-разному (например, вы можете получить доступ/интерпретировать 4 байта памяти в виде 1 целых чисел или 4 символа). Структуры, как вы знаете, являются простыми - набор разных, отдельных объектов с собственной памятью.

Обычно вам требуется Unions на более позднем этапе программирования по сравнению с Structs.