<<

in

• In C, we can create our own, complex types. • This is very convenient for modeling real-life objects by CS 201 defining our own data types that represent structured & Union collections of data pertaining to particular objects. • int, double, char are types of variables defined in C. by using structures, you can create your own types – a nice way to extend your programming languages. Debzani Deb • Unlike array, a structure can have individual components that contain data of different types. • Each of these data items is stored in a separate component of the structure and can be referred by using the component name.

1 2

Defining structure using struct Defining structure using # include • typedef allows us to associate a name with a struct line { Structure line has 4 Components of type int structure. (where else we saw typedef ?) int x1, y1; // Coordinates of one endpoint of a line typedef struct { int x2, y2; // Coordinates of other endpoint of a line int x1, y1; // Coordinates of one endpoint of a line }; int x2, y2; // Coordinates of other endpoint of a line } line_t; int main() { This defines the variable line1 to be a variable of type line int main() { struct line line1; line1 is now a variable of type line_t. line_t line1; } } • Variables may also be declared in the structure definition. • The typedef statement itself allocates no memory. struct line { • A variable declaration is required to allocate storage int x1, y1, x2, y2; space for a structured data object. } line1, line2;

3 4

Accessing components of a structure Assigning values to the components of a structure (from text) • To access a component of a structure, we can use the direct component selection operator, which is a dot/period. typedef struct { int main() { char name[10]; line_t line1; double diameter; line1.x1 = 3; int moons; line1.y1 = 5; double orbit_time, if(line1.y2 == 3) { retation_time; printf(“Y co-ord of end is 3\n”); } planet_t; } } • Direct component selection operator has the highest precedence. See table 11.1 in the text for the operator precedence.

5 6

1 Using Structures Structures as Input parameter • Structures can contain any C type, including arrays, • We can pass structure as input argument to a function. pointers or even other structures as components. • We have to make sure that the function prototype is introduced to after the structure is declared. • Initialization of structures: (similar to arrays) line_t line1 = {3, 5, 6, 7}; typedef struct { char name[10]; • Assignment of entire structures: double diameter; line2 = line1; // assign to each component of line2 a value of int moons; // the corresponding component of line1. double orbit_time, retation_time; ƒ Although C permits copying of entire structure, the equality } planet_t; and inequality operator can not be applied to a structured type as a unit. void print_planet (planet_t p1); if (line1 == line2) // Invalid int main() { ƒ Also you can’t use structures as argument to printf and … current_planet is passed as input scanf statement. print_planet(current_planet); argument and all the component values … of current_planet are copied to } corresponding formal parameter p1 7 in function print_planet. 8

Structure as output parameter Figure 11.5 Data Areas of main and scan_planet • Structures may contain large amount of data. during Execution of status = scan_planet • If a function needs to modify the content of a structure (¤t_planet); ƒ Use pointers to pass address of the structure to functions instead of passing the structure by value. Example, status = scan_planet(¤t_planet); // Statement in function main

9 10

Few notes about structure Structure as return type of a function

• Simple structure declaration • So far, we have seen that the structures are treated mostly like C’s Syntax: structName varName; Example, planet_p p1; simple data types (int, char etc.). One exception though (Anybody?) • A pointer to a structure • Comparatively, C’s processing of array differs a lot from its handling Syntax: structName * ptrName; Example: planet_p * p1_ptr; of simple data types. For example, array can’t be returned as a • Accessing a component of a structure function result. Syntax: varName.componentname; Example: p1.name • However, we can return structure as the function result. Returning a structure from a function means returning the values of all • Accessing a component of a pointer to a structure components. Syntax: (*ptrName).componentname; Example: (*p1_ptr).name /* The brackets are important cause “.” has higher priority than “*” */ • Indirect component selection operator ƒ C provides a single operator that combines the function of the indirection (pointer dereference) and component selection operator. ƒ For a pointer to a structure, a component can be accessed by using indirection operator “->” Syntax: ptrName -> componentName; Example: p1_ptr -> name;

11 12

2 Structures as components of structures (1) Structures as components of structures (2) • Send structure emp1 as input • Passing a pointer to a structure Structures can contain other structures as members. argument, modify it and then is more efficient. Example: Employee data base return the modified structure to the calling routine. update2 (&emp1); // in main … typedef struct { Member structures must be e = update1(emp1); // in main void update2 (emp_data_t *p) char dept_name[25]; defined beforehand, since the … { int dept_no; compiler must know their size. emp_data_t update1(emp_data_t emp) printf(“Enter department number: “); } department_t; { printf(“Enter department number: “); scanf(“%d”, &n); typedef struct { scanf(“%d”, &n); p ->dept.dept_no = n; emp.dept.dept_no = n; … char name[25]; The size of a pointer to a structure … } int employee_id; is just the size of the memory return emp; • Use -> instead of . to access department_t dept; address and therefore is known. } components of the structure, address_t * add_ptr; So struct address_t can be defined because p is a pointer to a Later. • Involves lots of copying of double salary; structure components to and structure. } emp_data_t; from the function.

13 14

Array of Structures Self-referencing Structures

• Structures may contain pointers to variables of their own type typedef struct { (recursive declaration). int id; struct list { int data; double gpa; struct list *next; } student_t; } a, b, c, d; • This may look initially strange, but in real life it is a very very student_t stulist[50]; useful construction. • By using self-referencing structures, variables of that structure type may be linked as follows

Accessing array elements a b c d data data data data for (i = 0; i < 50; i++) *next *next *next *next printf (“%d\n”, stulist[i].id);

15 16

Union (1) Union (2)

• C provides a data structure called union to deal with • Union provides a space in memory that can be interpreted in situations in which a data object can be interpreted an multiple ways. a variety of ways. union i_or_c { int i; • Like structure, union is a derived . On the char ch[4]; other hand, union allows its components to share the } n1, n2; same storage. • You can access n1 and n2 as either as an int or a char[]. •Example ƒ n1.i = 10; n2.ch[1] = ‘g’; typedef union { • Memory of a union is allocated according to the largest int i; interpretation. ƒ max(sizeof(int), 4*sizeof(char)) float f; } int_or_float; • Union can help you save space in memory – allocate one space in memory and use it in multiple ways. int_or_float a, b, c, d;

17 18

3 Union (3) Two interpretation of parameter hair • Unions are useful only if it is possible to determine within the program which interpretation is currently the valid interpretation. • Unions are mostly used as component of a larger structure, and the larger structure typically contains another component that determines which interpretation of the union is correct at the present time.

typedef union { Two interpretations of union h int wear_wig; char color[10]; 0 ? ? ? ? ? ? ? ? ? h.wear_wig } hair_t; e d d i s h \0 ? ? h.color typedef struct { int bald; hair_t h; } hair_info_t; Referencing the appropriate union component is programmer’s responsibility. 19 20

struct Summary union Summary

• struct is a simple tool – combines simpler •Pros types into one larger type. ƒ Very tight memory allocation • Powerful for all sort of uses – used throughout ƒ of polymorphism for types C programs and operating systems. ƒ Useful for maintaining memory that can be interpreted in • It makes modeling the real-life scenario easier. multiple ways • FILE * is a typedef’d struct, but you can use it • without knowing what’s inside it. ƒ You have to be careful with interpretation since types are very different at lower level. • You can extend the language by defining your ƒ Can make code very confusing if used without enough own types. documentation or improperly.

21 22

structs with union structs with union(cont.)

• The program in the next three slides creates a union status { struct personal { union status and makes it a component of int rank; long id; struct personal which is, in turn becomes a char deg[4]; float gpa; component of struct identity. } ; union status level; • The union uses the same storage space for } ; either component rank (int) or deg (char struct identity { char name[30]; string) depending on the answer to the user struct personal student; prompt for student status in function main. } ;

23 24

4 structs with union (cont.) structs with union (cont.) int main() { else { struct identity jb = {“Joe Brown”}, *ptr = &jb; printf (“Enter degree sought – ms or phd\n”); char u_g; scanf (“%s”, &jb.student.level.deg); jb.student.id = 123456; printf (“%s is a %s candidate\n”, jb.name, jb.student.gpa = 3.4; jb.student.level.deg); } /* end of else printf (“Enter Student Status – u or g\n”); scanf (“%c”, &u_g); printf (“%s %d %f\n”, jb.name, jb.student.id, jb.student.gpa); if (u_g == ‘u’) { printf (“%s %d %f\n”, ptr->name, printf (“Enter rank – 1, 2, 3, 4 or 5\n”); ptr->student.id, scanf (“%d”, &jb.student.level.rank); ptr->student.gpa); printf (“%s is level %d\n”, jb.name, jb.student.level.rank); return 0; } /* end of if } // end of main

25 26

5