简体   繁体   中英

C++ Unions bit fields task

Can somebody clear me out why would I use union and with what purpose the same address for the cin'ed variable and bit field (task from the Schildts C++ book)? In other words why would I use union for :

char ch; struct byte bit;

// Display the ASCII code in binary for characters.

#include <iostream>
#include <conio.h>
using namespace std;

// a bit field that will be decoded
struct byte {
  unsigned a : 1;
  unsigned b : 1;
  unsigned c : 1;
  unsigned d : 1;
  unsigned e : 1;
  unsigned f : 1;
  unsigned g : 1;
  unsigned h : 1;
};

union bits {
  char ch;
  struct byte bit;
} ascii ;

void disp_bits(bits b);

int main()
{
  do {
    cin >> ascii.ch;
    cout << ": ";
    disp_bits(ascii);
  } while(ascii.ch!='q'); // quit if q typed

  return 0;
}

// Display the bit pattern for each character.
void disp_bits(bits b)
{
  if(b.bit.h) cout << "1 ";
    else cout << "0 ";
  if(b.bit.g) cout << "1 ";
    else cout << "0 ";
  if(b.bit.f) cout << "1 ";
    else cout << "0 ";
  if(b.bit.e) cout << "1 ";
    else cout << "0 ";
  if(b.bit.d) cout << "1 ";
    else cout << "0 ";
  if(b.bit.c) cout << "1 ";
    else cout << "0 ";
  if(b.bit.b) cout << "1 ";
    else cout << "0 ";
  if(b.bit.a) cout << "1 ";
    else cout << "0 ";
  cout << "\n";
}

As a union, both ch and bit have an overlapped (shared) memory location. Store a character in it as ch and then reading bit produces the corresponding bit values for the character.

The real answer is - you wouldn't. Using bitfields in unions (or at all) like this is inherently unportable and may be undefined. If you need to fiddle with bits, you are much better off using the C++ bitwise operators.

Because the exercise demonstrates breaking up a value into bits using a bitfield and a union.

Assuming you know what a union is, if you were extracting something less repetitive from a binary value then you might want use it for clarity instead of making say two 24 bit integers from 48 chars out of shifts and masks.

But for the example in the task, shifts and masks would be much cleaner code, so you would probably not use a union for this task.

void disp_bits(unsigned b)
{ // not tested
    for ( int shift = 7; shift >= 0;  --shift )
        cout <<  ( ( b >> shift ) & 1 ) << ' ';

    cout << "\n";
}

Unions are used in network protocols. They can also be handy to fake out polymorphism in C. Generally they are a special use case.

In this example, it is sort of a dummy example to show you a little code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM