The keyword union is useful in defining a new data type like a structure. Its usage is also similar in syntax to a structure. But conceptually union and structures differ in the way they manage memory.In a structure memory is allocated for each member . In Union same memory is shared by all data members
Thus a structure variable requires memory = sum of the memory requirements of all its members
A union variable requires memory = maximum memory requirement of one member
Thus union allows us to interpret the same memory location
in different ways .
union sample
{
int x ;
float y ;
char ch ;
} p ;
Thus here p occupies 4 bytes. Byte 0 is interpreted as char ch . Byte 0 , byte1 together as int x , .All the four bytes together are read as float y . Changing the value of one data member may affect value of all other members.
union A
{
int x ;
char ch[2] ;
};
void main( )
{
union A var ;
var.x = 260 ;
printf(“%d %d” , var.ch[0] , var.ch[1] );
var.ch[0] += 10 ;
printf(“\nx = 5d” , var.x );
var.ch[1] += 2 ;
printf(“\nx = %d” , var.x);
}
Memory allocated for var => 2 Bytes or 16 bits
var.x = 260 -> 0000 0001 0000 0100
var.ch[0] - > 0000 0100 /* prints 4 */
var.ch[1] - > 0000 0001 /* prints 1 */
var.ch[0] += 10
var.ch[0] - > 0000 1110 /* now 14 */
var.x -> 0000 0001 0000 1110 /* now 270 */
var.ch[1] += 2 ;
var.ch[1] - > 0000 0011 /* 3 */
var.x - > 0000 0011 0000 1110
/* 512 + 256 + 14 = 782 */
Application of unions :-
There is a frequent requirement while interacting with hardware that the same data be interpreted differently
For e.g : Unions are useful in reading and manipulating CPU registers and availing various BIOS services (calling int86( ) function)
CPU registers are 2 bytes in size .We may access the information they store as 2 bytes entirely or as two information of one byte each.
An interrupt means to stop doing something and instead do something else. Keyboard interrupts are generated by pressing control key , (and or) alt keys , shift key along with some other key. An operating system has a table of interrupt numbers (Interrupt Vector Table IVT) and actions to be taken when the interrupt is encountered.
For e.g
ctrl + C : by pressing ctrl + C (^C) you might stop some
process
PrintScreen : By pressing the PrintScreen key you are generating an interrupt
An interrupt is serviced by the Operating system
You can call various dos interrupt services using int86( ) function (include
Declaration:
int int86(int intno, union REGS *inregs, union REGS *outregs);
inregs holds the values of A , B , C, D registers that are set before the function call
outregs holds the values of A , B , C , D registers after the call
Return Value:
The functions returns the value of AX register after completion of the software interrupt.
Programs: int86( ) function
#include
#include
#include
#define VIDEO 0x10
void movetoxy(int x, int y)
{
union REGS regs;
regs.h.ah = 2; /* set cursor position */
regs.h.dh = y;
regs.h.dl = x;
regs.h.bh = 0; /* video page 0 */
int86(VIDEO, ®s, ®s);
}
REGS
REGS (union)
The union REGS is used to pass information to and from these functions . It is defined as follows :-
union REGS {
struct WORDREGS x;
struct BYTEREGS h;
};
BYTEREGS and WORDREGS
Structures for storing byte and word registers
struct BYTEREGS {
unsigned char al, ah, bl, bh;
unsigned char cl, ch, dl, dh;
};
struct WORDREGS {
unsigned int ax, bx, cx, dx;
unsigned int si, di, cflag, flags;
};
Enumerated Data Types :-
The keyword enum helps us to define named integral constants .The advantage :
Improved readability and program documentation.
We use #defines to define constants. Here the datatype is not specific .But with enums the constants are of type int .
Program:
enum status { false , true };
here the constant false is assigned a value 0 and the constant true is assigned a value 1
We may have a code line such as
return true ;
or found = false ;
Program:
enum colors { red , green , blue } ;
Here the constant red has a value 0 , green 1 , blue 2
You might write code like
COLOR background, foreground;
background = blue ;
foreground = red;
Values may be redefined as
enum E1 { c1 = 100 , c2 , c3 };
In this case c1 is assigned a value 100 , c2 = 101 , c3 = 102 and so on .
By default the named constants take incremental values starting with 0 ( 0 , 1 , 2 , 3 .... )
One is free to change these values while defining such as
enum sample { x = 1 , y = 10 , z = 20 } ;
or
enum sample { a , b , c = 10 , d , e , f = 100 , g , h };
here values of a to h are a = 0 , b = 1 , c = 10 , d = 11 , e = 12 , f = 100 , g = 101 , h = 102
The C std library includes lot of enums and one can freely use them in code. IF given a choice between #define and enum in code, one is adviced to use enums liberally instead of #defines as the latter do not pin down the data type while enums are always considered integral constants.
The keyword typedef helps to rename datatypes or create datatypes to suit our needs . We can create user defined datatypes based on basic types like int, char, float, double or derived types like struct, union etc. Advantage is ability to call data type by a name that better defines its values and the code is better documented.
For e.g
typedef unsigned int number ;
/* program calls int by another name number */
number age ;
number quantity ;
The advantage is improved readability and program documentation .
typedef int boolean ;
typedef unsigned int WORD ;
You might now declare a variable as
Boolean status ;
WORD x ;
typedef are useful in structures
typedef struct
{
char *title ;
char *author ;
float cost ;
}Book ;
Book is a datatype we have defined .We might declare a variable
Book b1 , b2 ;
Note :
The keyword struct is not used while using data type Book to declare a variable.
