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

Я думаю, что вам нужно сделать следующее:

pid_t pid = fork();

Чтобы узнать больше о Linux API, перейдите на эту страницу онлайн-руководства или даже зайдите в свою терминал прямо сейчас и введите

man fork

Удачи!

384
задан Paolo Forgia 11 October 2017 в 09:24
поделиться

7 ответов

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

Для предоставления конкретного примера их использования я работал над интерпретатором Схемы только что, и я по существу накладывал типы данных Схемы на типы данных 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

редактирование: , Если Вы задаетесь вопросом, какие настройки x.b к 'c' изменяют значение x.a к, с технической точки зрения это не определено. На большинстве современных машин символ составляет 1 байт, и интервал составляет 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 байта интервала 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.

, НО

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

Для большего количества чтения на упорядочивании байтов, проверьте порядок байтов .

643
ответ дан Saurabh Hooda 11 October 2017 в 09:24
поделиться

У Вас есть он, это - все. Но так, в основном, какой смысл объединений?

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

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

Это для безопасности типов, это позволяет Вам сделать некоторый 'динамический контроль типов': компилятор знает, что Ваше содержание может иметь различные значения и точное значение как Ваш интерпретировать Вам решать во времени выполнения. Если у Вас есть указатель, который может указать на различные типы, НЕОБХОДИМО использовать объединение, иначе Вы кодируете, может быть неправильным из-за искажения проблем (в компиляторе говорится себе, "о, только этот указатель может указать на этот тип, таким образом, я могу оптимизировать те доступы...", и плохие вещи могут произойти).

10
ответ дан Piotr Lesnicki 11 October 2017 в 09:24
поделиться
  • 1
    Для решения пустого вопроса $values, приводящего к $value как пустой элемент промежутка, Вы можете echo trim( $value, '<span></span>'); – fyrye 5 February 2014 в 19:59

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

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

9
ответ дан CMS 11 October 2017 в 09:24
поделиться
  • 1
    Только упомянуть: с пустым $tags массив это стало бы <span></span> строка. – Bartosz Grzybowski 26 March 2012 в 13:11

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

11
ответ дан Gabriele D'Antona 11 October 2017 в 09:24
поделиться
  • 1
    Верный! Существует много способов сделать это. Я обычно использую это, потому что часто я хочу сделать что-то другое с целочисленной и десятичной частью. – lnafziger 13 June 2012 в 19:36

Вот короткий ответ: структура является рекордной структурой: каждый элемент в структуре выделяет новое место. Так, структура как

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

выделяет [по крайней мере 112] байты в памяти для каждого экземпляра. ("По крайней мере", потому что ограничения выравнивания архитектуры могут вынудить компилятор дополнить структуру.)

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

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

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

77
ответ дан Charlie Martin 11 October 2017 в 09:24
поделиться

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

union test {
    int a;
    long b;
}; 

могло иметь sizeof из 4 и требование выравнивания 4. И объединение и структура могут иметь дополнение в конце, но не в их начале. Запись в структуру изменяет только значение участника, записанного в. Запись в члена объединения представит значение всех других недопустимых участников. Вы не можете получить доступ к ним, если Вы не записали в них прежде, иначе поведение не определено. GCC обеспечивает как расширение, которое можно на самом деле считать от членов объединения, даже при том, что Вы не записали в них последний раз. Для Операционной системы не должно иметь значения, пишет ли пользовательская программа в объединение или в структуру. Это на самом деле - только выпуск компилятора.

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

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

some_test_pointer может указать на [1 110] или double*. При кастинге адреса типа test к [1 113] он укажет своему первому участнику, a, на самом деле. То же верно для объединения также. Таким образом, потому что объединение будет всегда иметь выравнивание по правому краю, можно использовать объединение для создания указывающий на некоторый тип допустимый:

union a {
    int a;
    double b;
};

, Что объединение на самом деле будет в состоянии указать на интервал и двойное:

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

на самом деле допустимо, как указано стандартом C99:

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

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

, компилятор не оптимизирует v->a = 10;, поскольку это могло влиять на значение [1 116] (и функция возвратится 10 вместо [1 118]).

39
ответ дан Steven Kirkland 11 October 2017 в 09:24
поделиться
  • 1
    Вместо "." для десятичного разделителя можно было также получить его от [[NSLocale currentLocale] objectForKey:NSLocaleDecimalSeparator]]. Таким образом, код будет также работать правильно на регионы с помощью запятой в качестве разделителя. – Frank 15 February 2014 в 21:42

там какой-либо хороший пример для предоставления различия между 'структурой' и 'объединением'?

мнимый коммуникационный протокол

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

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

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

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

49
ответ дан gsamaras 11 October 2017 в 09:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: