Lecture 10 union, enumeration, bit 1. Concepts of union Concepts of enumeration Bitwise operations Bit fields
1. Concepts of Unions Union is a user-defined data type that can store various types of data at the same memory location Similar to structures, a union is a collection of variables of different types Different from structure, only one type of the data can be stored in one field at any one time The sizeof union type is the maximum size of its variable types
1. Concepts of Unions Unions are used to save memory. They are useful for applications that involve multiple members, where values need not be assigned to all the members at any one time. Syntax union union-name { data_type var-name; ................................ };
Example: or union record { int i; char ch; float f; }; union record a; union record { int i; char ch; float f; } a; sizeof(a) = ? sizeof(record) = ? or union record { int i; char ch; float f; }; union record a; or typedef union { int i; char ch; float f; } record; record a;
record a; declare a memory space named a , a can be used to store an integer, char, or float number, can only hold one of them a time. The sizeof a is 4
Example record b; // can not be initialized b.i = 10; // b holds an integer, wrong syntax: b = 10; printf(“%d”, b.i); b.f= 10.5; // b holds an integer, wrong syntax: b = 10.5; float y; y= b.f ; b.ch= ‘A’; // b holds an integer, not b = ‘A’; printf(“%d”, b.ch);
Initializing Unions #include <stdio.h> typedef union { int x; int y; } POINT2; int main() { POINT2 P2; P2. x = 4; printf(“\n The x coordinate of P2 is %d”, P2.x); P2.y = 5; printf(“\n The y coordinate of P2 is %d”, P2.x); return 0; }
Arrays of Unions #include <stdio.h> union POINT { int x, y; }; int main() { int i; union POINT points[3]; points[0].x = 2; points[0].y = 3; points[1].x = 4; points[1].y = 5; points[2].x = 6; points[2].y = 7; for(i=0;i<3;i++) printf(“\n Coordinates of Point[%d] are %d and %d”, i, points[i].x, points[i].y); return 0; }
Unions inside Structures struct student { union { char name[20]; int roll_no; }; int marks; } st; /* in main() function*/ printf(“\n You can enter the name or roll number of the student”); printf(“\n Do you want to enter the name? (Y or N): ”); gets(choice); if(choice==‘y’ || choice==‘Y’) { printf(“\n Enter the name: ”); gets(st.name); } else { printf(“\n Enter the roll number: ”); scanf(“%d”, &stud.roll_no);
class code example person[0].id = 101; strcpy(person[0].name, “John”); person[0].job = ‘s’; person[0].category.class = 264; person[1].id = 102; strcpy(person[1].name, “Peter”); person[1].job = ‘t’; strcpy(person[1].category.position, “professor”); typedef union { int class; position[10]; } pType; typedef struct{ int id; char name[20]; char job; pType category; } recType; recType person[2];
printf(“ID Name Job Class/Position”); for (i = 0; i < 2; i++){ if (person[i].job ==‘s’) printf(“%-6d %-10s %-3c %-6s\n”, person[i].id, person[i].name, person[i].gender, person[i].job, person[0].category.class ); else printf(“%-6d %-10s %-3c %-6s\n”, person[i].id, person[i].name, person[i].gender, person[i].job, person[0].category.position ); } ID Name Job Class/Position John s 264 Peter t professor
2. Concepts of Enumeration enumeration is a user-defined data type that consists of integral constants. Used when a data only have a few possible values, enumeration data can be used. The sizeof emumeration datatype is equals to sizeof(int) Syntax, enum enum_name { const1, const2, ..., constN };
Examples enum BOOLEAN { false, true } flag; // internally false is assigned value 0, true value 1 flag = true; printf(“%d”, flag); // output 1 typedef enum BOOLEAN boolean; boolean flag1 = false; printf(“%d”, flag1); // output 0 or typedef enum { false, true } boolean; boolean flag = true;
Another example typedef enum { /* Defines an enumeration type */ saturday =1 , /* Names day and declares a */ sunday , /* variable named workday with monday, /* that type */ Tuesday =5, wednesday, /* wednesday is associated with 6 */ thursday, friday , } dayType; dayType today = wednesday; dayType nextday = today+1; printf(“%d”, nextday); // will print value 7 enum { yes, no } response;
3. Bitwise operations in C A bitwise operation operates on one or more bit patterns or binary numerals at the level of their individual bits Bitwise operation is a fast, primitive operation directly supported by the processor It is used to manipulate values for comparisons and calculations.
Available bitwise operations in C unsigned int a, b, c; & AND e.g. c = a & b; &= AND Assignment, e.g. a &= b; a = a & b; | OR e.g. c = a | b; |= OR Assignment e.g. a |= b; a = a | b; ^ XOR e.g. c = a ^ b; ^= XOR Assignment e.g. a ^= b; a = a ^ b; ~ one's compliment e.g c = ~ a; << Shift Left e.g c = a << 2; >> Shift Right e.g. c = a >> 2; <<= Shift Left Assignment e.g. a <<= 2; a = a << 2; >>= Shift Right Assignment e.g a >>= a; a = a >> 2;
Examples int main() { unsigned int a = 60; /* 60 = 0000 0000 0011 1100 */ unsigned int b = 13; /* 13 = 0000 0000 0000 1101 */ unsigned int c = 0; c = a & b; /* 12 = 0000 0000 0000 1100 */ } unsigned int a = 60; /* 60 = 0000 0000 0011 1100 */ unsigned int b = 13; /* 13 = 0000 0000 0000 1101 */ c = a | b; /* 61 = 0000 0000 0011 1101 */
XOR and one’s complement main() { unsigned int a = 60; /* 60 = 0000 0000 0011 1100 */ unsigned int b = 13; /* 13 = 0000 0000 0000 1101 */ unsigned int c = 0; c = a ^ b; /* 49 = 0000 0000 0011 0001 */ } unsigned int Value=4; /* 4 = 0000 0000 0000 0100 */ Value = ~ Value; /* 251 = 1111 1111 1111 1011 */
Example of shift main() { unsigned int value=4; /* 4 = 0000 0000 0000 0100 */ unsigned int shift=2; value = value << shift; /* 16 = 0000 0000 0001 0000 */ value <<= shift; /* 64 = 0000 0000 0100 0000 */ printf("%d\n", value); /* Prints 64 */ }
Example of shift int main() { unsigned long int bytes=256; /* 00000000 00000000 00000000 10000000 */ do printf("%3ld \n", bytes); bytes >>= 1; /* 00000000 00000000 00000000 01000000 */ } while (bytes); } 256 128 64 32 16 8 4 2 1
4. Bit fields A bit field is used in computer programming to compactly store multiple logical values as a short series of bits where each of the single bits can be addressed separately A bit field is most commonly used to represent integral types of known, fixed bit-width A well-known usage of bit-fields is to represent single bit flags with each flag stored in a separate bit
The application of bit fields in IP header
Example of using bit fields typedef struct packet-data { unsigned a:2; // has has 2 bits unsigned b:6; // has has 6 bits unsigned c:4; // has has 4 bits unsigned d:4; // has has 4 bits int i:16; // has 16 bits } packetType; packetType data; data.a = 3; data.b = 7; data.c = 9; data.d = 15; data.i = 256; printf(“%d, %d, %d, %d”, data.a, data.b, data.c, data.d); printf(“%u, %o, %x, %d”, data.a, data.b, data.c, data.d); a b c d i 1 1 0 0 0 1 1 1 1 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0