940 likes | 2.25k Views
Structures, Unions in C. Basic of Structures. Definition: A collection of one or more different variables with the same handle (same name) Structures are customized (programmer-defined) data types Keyword struct is used to declare structures and create variables of customized data types
E N D
Basic of Structures • Definition: A collection of one or more different variables with the same handle (same name) • Structures are customized (programmer-defined) data types • Keyword structis used to declare structures and create variables of customized data types • Variables in a structure are called members struct Point pt; Variables pt, pt1, pt2 are of type “Point” Declaration of new data type “Point” struct Point { char name[30]; int x; int y; }; struct Point { … . . } pt1, pt2;
Memory View of Structures pt struct Point pt; Name y x Memory allocated for pt = SUM of memories allocated for its member variables
Basic of Structures (contd…) • Access a member of structure (. notation to access members) • members can be explicitly assigned values pt.Name=“firstPoint”; pt.x=10; pt.y=20; structure-name.member printf(“x = %d, y = %d\n”, pt.x, pt.y);
Basic of Structures (contd…) • Structures can be initialized during declaration struct Point pt={“newPt”, 10, 20}; • By default, they are initialized to 0 (or `\0') • Size of a structure is the combined size of its members
struct Apt { int Number; intMBedroomSize; // in square feet intBedroomSize; intBalconySize; float BathSize; double MBathSize; }; // No variables created // } name1, name2, name3; // Now variables are made. struct Apt MyPlace = {311, 400, 200, 100, 125.50, 175.50}; // New global variable int main() { printf(“Apt No: %d\n", MyPlace.Number); printf("MyBedroom: %d\n", MyPlace.MBedroomSize); printf("Bedroom: %d\n", MyPlace.BedroomSize); printf(“Balcony: %d\n", MyPlace.BalconySize); printf("Bath: %f\n", MyPlace.BathSize); printf("My Bath: %lf\n", MyPlace.MBathSize); return 0; }
Structures and Functions • When structures are passed into functions all of their values are copied. (pass by value, like basic data types. Arrays are different) • A function must return the structure to affect the target structure. • This is a lot of copying of variable values onto and off the stack. (inefficient) • Pointers will be used to make this efficient.
Pointers to Structures • Pointers are an easier way to manipulate structure members by reference • The entire structure is not passed by value, only the address of the first member • Use arrow operator () for accessing the struct element struct Date MyDate, *DatePtr; DatePtr = &MyDate; DatePtr->month = 2; DatePtr->day = 22;
Nested Structures • Structs can also contain other structs as members • To access its element: l1 pt1 pt2 struct Line { struct Point pt1; struct Point pt2; }; struct Line l1; y y x x Name Name The . operator has left-to-right associativity l1.pt1.x=10;
Array of Structures • Array of Structures act like any other array. • Memory occupied: the dimensions of the array multiply by sizeof(struct tag) • (Remember) sizeof() is compile time function struct Point pt[3]; pt[0].name = “A”; pt[0].x = 0; pt[0].y = 1; pt[1].name = “B”; pt[1].x = 4; pt[1].y = 1; pt[2].name = “mid”; pt[2].x = (pt[0].x + pt[1].x)/2; pt[2].y = (pt[0].y + pt[1].y)/2;
Pointers in Structures struct Point pt; struct Point { char *namePtr; int x; int y; }; • A structure can have a pointer as its member pt.namePtr=(char *) malloc(20*sizeof(char)); *(pt.namePtr)=“lastPoint”; pt y namePtr x pt y namePtr x lastPoint \0
Pointer to Structures • A pointer to a structure can be defined struct Point p1, *ptr; ptr=&p1; p1.x=10 ≡ptrx =10 ≡ (*ptr).x=10 ≡ (&p1)x = 10
Self referencing Structures • Useful in data structures like trees, linked lists. • It is illegal for a structure to contain an instance of itself. • Solution: Have a pointer to another instance. n1 n2 value nextPtr value nextPtr struct lnode { /* the linked list node */ int value; struct lnode *nextPtr; /* pointer to next node */ } n1,n2; 0 NULL 0 NULL
Self referencing Structures n1.value=10; n1.nextPtr=&n2; n2.value=20; n2.nextPtr=NULL; struct lnode *basePtr=&n1; basePtr 0x1000 n1 n2 value value nextPtr nextPtr 10 0x2000 20 NULL 0x1000 0x2000
Typedef typedef int length; • Use typedef for creating new data type names this the name length a synonym (alias) for int. Afterwards, you can do: • In context of structs, you can do: length x = 4; struct Point { int x; int y; }; typedef struct Point myPoint; myPoint p1; struct Point p2; p1.x=10; typedef struct Point *pointPtr; pointPtr p1; struct Point p2; p2.x=20; p1.x=10; ?? p1x=10; ?? p1=&p2; p1x=10; ?? p1=(pointPtr) malloc(sizeof(struct Point)); p1x=10; ?? typedef struct lnode { . . } myNode; myNode n1, *ptr; typedef struct { . . } myNode; myNode n1, *ptr;
Unions • A union is a memory location that is shared by two or more different types of variables. • Each of ival, fval, cval have the same location in memory. • sizeof(union …) = maximum of sizeof(field) • Usage is similar to that of structs: • Up to programmer to determine how to interpret a union (i.e. which member to access) and used for low-level programming union u_tag { int ival; float fval; char cval; } u; u.ival or u.cval
padding c EF BE AD DE i Example union AnElt { int i; char c; } elt1, elt2; elt1.i = 4; elt2.c = ’a’; elt2.i = 0xDEADBEEF;
Unions • Storage • size of union is the size of its largest member • avoid unions with widely varying member sizes; for the larger data types, consider using pointers instead • Initialization • Union may only be initialized to a value appropriate for the type of its first member
Bit-fields • When storage is high cost affair, we need to use memory efficiently (e.g in embedded systems) • Here each of the element takes a bit of memory (1 bit) • The number following the colons represent the field length in bits. struct { unsigned pin1 : 1; unsigned pin2 : 2; unsigned pin3 : 1; } flags;