< .Net Type, Variable & Operator 5 | Main | .Net Type, Variable & Operator 7 >


 

 

Data Types, Variables and Operators 6

 

 

 

 

 

 

The discussion and the codes used supposed to be based on the new C++ .NET. The following are the topics in this part.

  1. Unions

  2. Declaring a Union

  3. Using a Union

  4. C++ Bit Fields

 

Unions

 

A union is a user-defined data or class type that, at any given time, contains only one object from its list of members (although that object can be an array or a class type).

union [tag] { member-list } [declarators];

[union] tag declarators;

The member-list of a union represents the kinds of data the union can contain. A union requires enough storage to hold the largest member in its member-list.

 

Declaring a Union

 

Begin the declaration of a union with the union keyword, and enclose the member list in curly braces:

// declaring a union

union DATATYPE    // Declare union type

{

    char   ch;

    int    i;

    long   l;

    float  f;

    double d;

} var1;          // Optional declaration of union variable

 

int main()

{  }

// No output

Using a Union

 

A C++ union is a limited form of the class type. It can contain access specifiers (public, protected, private), member data, and member functions, including constructors and destructors. It cannot contain virtual functions or static data members. It cannot be used as a base class, nor can it have base classes. Default access of members in a union is public. A C union type can contain only data members. In C, you must use the union keyword to declare a union variable. In C++, the union keyword is unnecessary:

union DATATYPE var2;   // C declaration of a union variable

DATATYPE var3;         // C++ declaration of a union variable

A variable of a union type can hold one value of any type declared in the union. Use the member-selection operator (.) to access a member of a union:

var1.i = 6;           // Use variable as integer

var2.d = 5.327;       // Use variable as double

You can declare and initialize a union in the same statement by assigning an expression enclosed in braces. The expression is evaluated and assigned to the first field of the union. Consider the following example.

// Variables.cpp : main project file.

// using a union

// compile with: /clr

#include "stdafx.h"

#include <stdio.h>

 

using namespace System;

 

union NumericType

{

    int         iValue;

    long        lValue;

    double      dValue;

};

 

int main()

{

      union NumericType Values = { 100 };   // iValue = 10

      printf_s("Values.iValue = %d\n", Values.iValue);

      Values.dValue = 3.1416;

      printf_s("Values.dValu = %f\n", Values.dValue);

}

 

Output:

UNion program output sample

 

The NumericType union is arranged in memory (conceptually) as shown in the following figure. Storage of Data in NumericType Union

 

Numeric Type Union Data Storage

 

The following code shows how you can use a union to store several different types of variables:

 

// Variables.cpp : main project file.

// unions

// compile with: /clr

#include "stdafx.h"

#include <stdio.h>

 

using namespace System;

 

// Declare a union that can hold data of types

// char, int or char *.

union ToPrint

{

      char chVar;

      int iVar;

      char *szVar;

};

 

// Declare an enumerated type

// that describes what type to print.

enum PrintType

{ CHAR_T, INT_T, STRING_T };

 

void Print(ToPrint Var, PrintType Type)

{

      switch(Type)

      {

            case CHAR_T: printf_s( "%c", Var.chVar );

                  break;

            case INT_T: printf_s( "%d", Var.iVar );

                  break;

            case STRING_T: printf_s( "%s", Var.szVar );

                  break;

    }

}

 

int main()

{

      return 0;

}

// Output: none

C++ Bit Fields

 

Classes and structures can contain members that occupy less storage than an integral type. These members are specified as bit fields. The syntax for bit-field member-declarator specification follows:

declarator  : constant-expression

The declarator (optional) is the name by which the member is accessed in the program. It must be an integral type (including enumerated types). The constant-expression specifies the number of bits the member occupies in the structure. Anonymous bit fields that is, bit-field members with no identifier, can be used for padding. An unnamed bit field of width 0 forces alignment of the next bit field to the next type boundary, where type is the type of the member. The following example declares a structure that contains bit fields:

// bit fields

// compile with: /LD

struct Date {

   unsigned short nWeekDay  : 3;    // 0..7   (3 bits)

   unsigned short nMonthDay : 6;    // 0..31  (6 bits)

   unsigned short nMonth    : 5;    // 0..12  (5 bits)

   unsigned short nYear     : 8;    // 0..100 (8 bits)

};

The conceptual memory layout of an object of type Date is shown in the following figure.

 

 

Date Object Memory Layout graphic

 

Memory layout of Date object

 

 

 

 

 

 

 

Note that nYear is 8 bits long and would overflow the word boundary of the declared type, unsigned short. Therefore, it is begun at the beginning of a new unsigned short. It is not necessary that all bit fields fit in one object of the underlying type; new units of storage are allocated, according to the number of bits requested in the declaration. The ordering of data declared as bit fields is from low to high bit, as shown in the figure above and this is Microsoft implementation. If the declaration of a structure includes an unnamed field of length 0, as shown in the following example,

// bit fields

// compile with: /LD

struct Date {

   unsigned nWeekDay  : 3;    // 0..7   (3 bits)

   unsigned nMonthDay : 6;    // 0..31  (6 bits)

   unsigned           : 0;    // Force alignment to next boundary.

   unsigned nMonth    : 5;    // 0..12  (5 bits)

   unsigned nYear     : 8;    // 0..100 (8 bits)

};

the memory layout is as shown in the following figure.

 

Date Object Layout 0 Length Bit Field

 

Layout of Date object with zero-length bit field

 

The underlying type of a bit field must be an integral type.

 

Part 1 | Part 2 | Part 3 | Part 4 | Part 5 | Part 6 | Part 7 | Part 8 | Part 9 | Part 10

 


 

< .Net Type, Variable & Operator 5 | Main | .Net Type, Variable & Operator 7 >