Почему мой союз не показывает правильные значения?

union
{ int i;
  bool b;
} x;

x.i = 20000;
x.b = true;
cout << x.i;

Он печатает 19969. Почему он не распечатывает 20000?

Ответы

Ответ 1

A union не является struct. В union все данные занимают одно и то же пространство и могут быть обработаны как разные типы через свои имена полей. Когда вы назначаете true на x.b, вы перезаписываете младшие разряды 20000.

Более конкретно:

20000 в двоичном формате: 100111000100000

19969 в двоичном формате: 100111000000001

Здесь произошло то, что вы поместили однобайтовое значение 1 (00000001) в 8 младших битов 200000.

Если вы используете struct вместо union, у вас будет место как для int, так и bool, а не только для int, и вы увидите ожидаемые результаты.

Ответ 2

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

union Vector3
{
  int v[3];
  struct
  {
    int x, y, z;
  };
};

Позволяет вам получить доступ к трем целым числам либо по имени (x, y и z), либо как массив (v).

Ответ 3

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

Иногда союзы намеренно используются для кастомизации типа (например, глядя на байты, которые составляют float). В этом случае вам решать, что вы получаете. Тип языка пытается дать вам шанс на бой, но он не может реально гарантировать многое.

Ответ 4

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