Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 43, средняя оценка - 4.84
Shandr_71
13 / 13 / 1
Регистрация: 05.12.2011
Сообщений: 84
#1

Union - C++

24.02.2012, 20:54. Просмотров 5472. Ответов 13
Метки нет (Все метки)

Возник вопрос про объединения. В книгах я встречал лишь случай, когда размер одного из полей больше или равен сумме размеров остальных. Например:
C++
1
2
3
4
5
union
{
    double a;
    char b[2];
};
А как будет работать объединение в таком случае:
C++
1
2
3
4
5
6
7
union
{
    double a;
    double b;
    int c;
    int d;
};
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
24.02.2012, 20:54     Union
Посмотрите здесь:

C++ Объединения (union)
Union C++
union с методами C++
Union - Объединения C++
C++ Управляемый value union
Как обращаться к Union C++
обьединения union C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Jupiter
Каратель
Эксперт C++
6548 / 3968 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
24.02.2012, 20:58     Union #2
Цитата Сообщение от Shandr_71 Посмотреть сообщение
В книгах я встречал лишь случай, когда размер одного из полей больше или равен сумме размеров остальных.
лол что?

Цитата Сообщение от Shandr_71 Посмотреть сообщение
А как будет работать объединение в таком случае:
C++
1
2
3
4
5
6
7
union
{
* * double a;
* * double b;
* * int c;
* * int d;
};
union на то и union чтоб хранить одни данные разных типов
Shandr_71
13 / 13 / 1
Регистрация: 05.12.2011
Сообщений: 84
24.02.2012, 21:14  [ТС]     Union #3
Мне интересно, как будет выделена память во втором случае.
Jupiter
Каратель
Эксперт C++
6548 / 3968 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
24.02.2012, 21:26     Union #4
размер юниона всегда равен размеру наибольшего типа, который содержит юнион
Shandr_71
13 / 13 / 1
Регистрация: 05.12.2011
Сообщений: 84
24.02.2012, 21:31  [ТС]     Union #5
В моем примере тип double - самый большой (8 байт), но для хранения всех членов нужно минимум 16 байт.
Jupiter
Каратель
Эксперт C++
6548 / 3968 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
24.02.2012, 21:35     Union #6
Цитата Сообщение от Shandr_71 Посмотреть сообщение
В моем примере тип double - самый большой (8 байт), но для хранения всех членов нужно минимум 16 байт.
ещё раз повторяю - в юнионах одни данные, а мемберы юниона лишь позволяют интепретировать эти данные поразному, открой книжку и ещё раз прочитай что такое юнион, и посмотри что выведет sizeof этого юниона!
silent_1991
Эксперт С++
4949 / 3025 / 149
Регистрация: 11.11.2009
Сообщений: 7,025
Завершенные тесты: 1
24.02.2012, 21:51     Union #7
Shandr_71, не путайте union и struct, это совершенно разные вещи.
Shandr_71
13 / 13 / 1
Регистрация: 05.12.2011
Сообщений: 84
24.02.2012, 22:00  [ТС]     Union #8
Я ничего не путаю.
Тогда так поставлю вопрос:
|---- a ----|
|---- b ----|
|--c----d--|
|--8 байт--|

Память будет распределяться таким образом?
silent_1991
Эксперт С++
4949 / 3025 / 149
Регистрация: 11.11.2009
Сообщений: 7,025
Завершенные тесты: 1
24.02.2012, 22:29     Union #9
Shandr_71, память никак не будет распределяться. Будет выделено ровно столько памяти, чтобы вместить максимальный тип. Любая переменная - просто некоторый набор битов. Если тип double имеет размер 8 байт (64 бита), а int - 4 байта (32 бита), то, разумеется, можно использовать младшие 32 бита переменной типа double под переменную типа int. Вот union и позволяет интерпретировать некоторый набор битов по-разному, в зависимости от наименования поля union. Вот пример:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
 
union Foo
{
    char a;
    int b;
    double c;
};
 
int main()
{
    Foo bar;
    
    bar.a = 49;
    
    std::cout << bar.a << std::endl;
    std::cout << bar.b << std::endl;
    std::cout << bar.c << std::endl;
    std::cout << sizeof(bar) << std::endl;
    
    return 0;
}
У меня программа выводит:
Код
1
49
2.42092e-322
8
И a, и b, и c на самом деле расположены в одной и той же памяти размером 8 байт (размер типа double). Видно, что когда мы выводим char, значение 49 интерпретируется как символ и выводится символ '1' (с кодом 49). Когда мы выводим int, значение интерпретируется как целое и выводится 49, как и ожидалось. При выводе double на первый взгляд кажется, что там мусор, но нет, просто тип double хранится в особом формате, и тот набор битов, который сейчас записан в памяти, ассоциированной с переменной bar, интерпретируется именно как число 2.42092e-322.
go
Эксперт C++
3584 / 1364 / 128
Регистрация: 16.04.2009
Сообщений: 4,528
24.02.2012, 22:36     Union #10
Цитата Сообщение от Shandr_71 Посмотреть сообщение
В моем примере тип double - самый большой (8 байт), но для хранения всех членов нужно минимум 16 байт.
Цитата Сообщение от silent_1991 Посмотреть сообщение
и struct,
Есть вероятность, что размер структуры не будет равен сумме размеров всех ее полей.
silent_1991
Эксперт С++
4949 / 3025 / 149
Регистрация: 11.11.2009
Сообщений: 7,025
Завершенные тесты: 1
25.02.2012, 14:08     Union #11
Цитата Сообщение от go Посмотреть сообщение
Есть вероятность, что размер структуры не будет равен сумме размеров всех ее полей.
И что? В моём сообщении и намёка на размер не было. Суть не в том, чтобы разобраться в выравнивании, а в том, что разница структуры и объединения в том, что структура одновременно может хранить несколько значений разных типов (т.е. её размер будет как минимум равен сумме размеров входящих в него полей), а объединение - только одно значение одного из типов её полей (т.е. размер будет равен максимальному из размеров входящих в неё полей).
Denno
51 / 51 / 6
Регистрация: 21.10.2012
Сообщений: 187
Завершенные тесты: 3
22.06.2013, 08:25     Union #12
Цитата Сообщение от go Посмотреть сообщение
Есть вероятность, что размер структуры не будет равен сумме размеров всех ее полей.
А в каком случае размер структуры не будет равен сумме размеров всех ее полей, можно пример ?
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1242 / 991 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
22.06.2013, 08:33     Union #13
C++
1
2
3
4
struct x {
    char a;
    int b;
};
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
23.06.2013, 14:02     Union
Еще ссылки по теме:

Union, struct C++
Union C++
Тип объединения union C++
C++ Union внутри struct
Union-объеденения C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
silent_1991
Эксперт С++
4949 / 3025 / 149
Регистрация: 11.11.2009
Сообщений: 7,025
Завершенные тесты: 1
23.06.2013, 14:02     Union #14
@Denno, почитайте про выравнивание, оттуда ноги растут.
Yandex
Объявления
23.06.2013, 14:02     Union
Ответ Создать тему
Опции темы

Текущее время: 22:12. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru