что это значит, говоря, что членами профсоюза можно манипулировать только по одному? - PullRequest
3 голосов
/ 23 сентября 2019

Я только читал теорию о союзах и стеках.В книге Э. Балагурусами («Объектно-ориентированное программирование на С ++») говорится, что «членами союза можно манипулировать только по одному за раз».Но я возился с профсоюзами.Я сделал это без ошибок.

#include <iostream>
#include <iomanip>
#include "ConsoleApplication1.h"

using namespace std;
//user defined data types
#define writeln(x)(cout<<x<<endl)
union result
{
    int marks;
    char grade;
    float percent;
};
int main()
{  
    result result;
    result.marks = 90;
    result.grade = 'a';
    writeln(result.grade);
    writeln(result.marks);
}

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

.

Ответы [ 3 ]

6 голосов
/ 23 сентября 2019

Это означает, что вы вызываете неопределенное поведение.Давайте посмотрим, что происходит с каждой строкой кода:

result result;         // ok, you have declared an union
result.marks = 90;     // ok, result.marks is defined
result.grade = 'a';    // ok, result.grade is defined, but result.mark is no longer
writeln(result.grade); // ok, access to the last written member of the union
writeln(result.marks); // UB: access to a member which is not the last writter

UB действительно неприветливо для новичков, потому что может случиться что угодно:

  • компилятор может обнаружить проблему и вызватьпредупреждение или ошибка (но это не обязательно ...)
  • writeln(result.marks) может написать 90 или код символа 'a' (97) или ничего, или что-то еще дажезавершить программу

И, как бы то ни было, вы можете получить ожидаемое поведение за один прогон, а позже - другое.

Короче говоря, не играйте счто ...

1 голос
/ 23 сентября 2019
  • результат результата;
  • result.marks = 90;

    // начало 4 байта с & result (память: 5a 00 00 00 - 90) ПРИМЕЧАНИЕ: механизм, используемый памятью big endian или little endian 90 равен 00 00 00 5a, big endian памяти будет 5a 00 00 00, а little endian будет противоположен memory when assign marks

  • result.grade = 'a';

    // начало 1 байта из & result (память: 61 - 'a') memory when assign grade

  • writeln (result.grade);// получаем начало в 1 байт в & result

  • writeln (result.marks);// получаем 4 байта в начале & result
0 голосов
/ 23 сентября 2019

В union каждая переменная разделяет одну и ту же память.По этой причине вы получаете выходы 'a' и '97'.

result result;
result.marks = 90; // memory value is 90
result.grade = 'a'; // memory value is 97 ('a')
writeln(result.grade); // print 97 ('a')
writeln(result.marks); // print 97
...