Structures Often we want to be able to manipulate logical entities as a whole For example, complex numbers, dates, student records, etc Each of these must be composed of more than one variable, but are logically units A struct (short for structure) is a collection of variables of different types, gathered into one super-variable It is used to define more complex data types Variables in a struct are called members or fields
Example – complex numbers. The following is the definition of a new variable of type complex number: struct complex { int real; int img; }; Once we define a structure, we can treat it as any type. In a program, we can then write: struct complex num1, num2, num3;
Access structure members If A is of some structure with a member named x, then A.x is that member of A struct complex C; C.real = 0; If A is a pointer to a structure with a member x, then A->x is that member of the variable pointed by A. This is simply shorthand for - (*A).x struct complex *pc = &C; pc->real = 1;
A more convenient usage with typedef An alternative definition: typedef struct complex_t { int real; int img; } complex; Now the program has a new variable type - complex. This way we dont have to write struct complex every time! For example, we can define two complex numbers in the following line: complex num1, num2;
Examples AddComplex.c
AddComplex – step by step complex a, b, c; printf(…"); scanf("%lf%lf",&(a.real),&(a.img)); printf(…"); scanf("%lf%lf",&(b.real),&(b.img)); c = AddComp(a,b); printf(result = %g+%gi\n",c.real,c.img); return 0; …… realimg a …… realimg b …… realimg c
AddComplex – step by step complex a, b, c; printf(…"); scanf("%lf%lf",&(a.real),&(a.img)); printf(…"); scanf("%lf%lf",&(b.real),&(b.img)); c = AddComp(a,b); printf(result = %g+%gi\n",c.real,c.img); return 0; …… realimg a …… realimg b …… realimg c
AddComplex – step by step complex a, b, c; printf(…"); scanf("%lf%lf",&(a.real),&(a.img)); printf(…"); scanf("%lf%lf",&(b.real),&(b.img)); c = AddComp(a,b); printf(result = %g+%gi\n",c.real,c.img); return 0; realimg a …… realimg b …… realimg c
AddComplex – step by step complex a, b, c; printf(…"); scanf("%lf%lf",&(a.real),&(a.img)); printf(…"); scanf("%lf%lf",&(b.real),&(b.img)); c = AddComp(a,b); printf(result = %g+%gi\n",c.real,c.img); return 0; realimg a …… realimg b …… realimg c
AddComplex – step by step complex a, b, c; printf(…"); scanf("%lf%lf",&(a.real),&(a.img)); printf(…"); scanf("%lf%lf",&(b.real),&(b.img)); c = AddComp(a,b); printf(result = %g+%gi\n",c.real,c.img); return 0; realimg a realimg b …… realimg c
AddComplex – step by step complex a, b, c; printf(…"); scanf("%lf%lf",&(a.real),&(a.img)); printf(…"); scanf("%lf%lf",&(b.real),&(b.img)); c = AddComp(a,b); printf(result = %g+%gi\n",c.real,c.img); return 0; realimg a realimg b …… realimg c
AddComplex – step by step complex AddComp(complex x, complex y) { complex z; z.real = x.real + y.real; z.img = x.img + y.img; return z; } realimg x realimg y …… realimg z
AddComplex – step by step complex AddComp(complex x, complex y) { complex z; z.real = x.real + y.real; z.img = x.img + y.img; return z; } realimg x realimg y …6.0 realimg z
AddComplex – step by step complex AddComp(complex x, complex y) { complex z; z.real = x.real + y.real; z.img = x.img + y.img; return z; } realimg x realimg y realimg z
AddComplex – step by step complex AddComp(complex x, complex y) { complex z; z.real = x.real + y.real; z.img = x.img + y.img; return z; } realimg x realimg y realimg z
AddComplex – step by step complex a, b, c; printf(…"); scanf("%lf%lf",&(a.real),&(a.img)); printf(…"); scanf("%lf%lf",&(b.real),&(b.img)); c = AddComp(a,b); printf(result = %g+%gi\n",c.real,c.img); return 0; realimg a realimg b realimg c
AddComplex – step by step complex a, b, c; printf(…"); scanf("%lf%lf",&(a.real),&(a.img)); printf(…"); scanf("%lf%lf",&(b.real),&(b.img)); c = AddComp(a,b); printf(result = %g+%gi\n",c.real,c.img); return 0; realimg a realimg b realimg c
Exercise Implement the MultComplex function – Input - two complex numbers Output – their multiplication Note - If x=a+ib and y=c+id then: z = xy = (ac-bd)+i(ad+bc) Write a program that uses the above function to multiply two complex numbers given by the user
Solution MultiplyComplex.c
Miscellaneous structure trivia Structure members may be ordinary variable types, but also other structures and even arrays! Structures can therefore be rather large and take up a lot of space Many times we prefer to pass structures to functions by address, and not by value Thus a new copy of the structure is not created – just a pointer to the existing structure
More trivia Structures cannot be compared using the == operator They must be compared member by member Usually this will be done in a separate function Structures can be copied using the = operator Member-wise copy
Example Is_In_Circle.c
Is_in_circle – step by step printf(Enter dot\n"); scanf("%lf%lf",&d.x,&d.y); printf("Enter circle center\n"); scanf("%lf%lf",&c.center.x,&c.center.y); printf("Enter circle radius\n"); scanf("%lf",&c.radius); if (IsInCircle(&d, &c)) printf("dot is in circle\n"); else printf("dot is out of circle\n"); …… yx d (dot)c (circle) …… yx center (dot) radius …
Is_in_circle – step by step printf(Enter dot\n"); scanf("%lf%lf",&d.x,&d.y); printf("Enter circle center\n"); scanf("%lf%lf",&c.center.x,&c.center.y); printf("Enter circle radius\n"); scanf("%lf",&c.radius); if (IsInCircle(&d, &c)) printf("dot is in circle\n"); else printf("dot is out of circle\n"); …… yx d (dot)c (circle) …… yx center (dot) radius …
Is_in_circle – step by step printf(Enter dot\n"); scanf("%lf%lf",&d.x,&d.y); printf("Enter circle center\n"); scanf("%lf%lf",&c.center.x,&c.center.y); printf("Enter circle radius\n"); scanf("%lf",&c.radius); if (IsInCircle(&d, &c)) printf("dot is in circle\n"); else printf("dot is out of circle\n"); yx d (dot)c (circle) …… yx center (dot) radius …
Is_in_circle – step by step printf(Enter dot\n"); scanf("%lf%lf",&d.x,&d.y); printf("Enter circle center\n"); scanf("%lf%lf",&c.center.x,&c.center.y); printf("Enter circle radius\n"); scanf("%lf",&c.radius); if (IsInCircle(&d, &c)) printf("dot is in circle\n"); else printf("dot is out of circle\n"); yx d (dot)c (circle) …… yx center (dot) radius …
Is_in_circle – step by step printf(Enter dot\n"); scanf("%lf%lf",&d.x,&d.y); printf("Enter circle center\n"); scanf("%lf%lf",&c.center.x,&c.center.y); printf("Enter circle radius\n"); scanf("%lf",&c.radius); if (IsInCircle(&d, &c)) printf("dot is in circle\n"); else printf("dot is out of circle\n"); yx d (dot)c (circle) 0.0 yx center (dot) radius …
Is_in_circle – step by step printf(Enter dot\n"); scanf("%lf%lf",&d.x,&d.y); printf("Enter circle center\n"); scanf("%lf%lf",&c.center.x,&c.center.y); printf("Enter circle radius\n"); scanf("%lf",&c.radius); if (IsInCircle(&d, &c)) printf("dot is in circle\n"); else printf("dot is out of circle\n"); yx d (dot)c (circle) 0.0 yx center (dot) radius …
Is_in_circle – step by step printf(Enter dot\n"); scanf("%lf%lf",&d.x,&d.y); printf("Enter circle center\n"); scanf("%lf%lf",&c.center.x,&c.center.y); printf("Enter circle radius\n"); scanf("%lf",&c.radius); if (IsInCircle(&d, &c)) printf("dot is in circle\n"); else printf("dot is out of circle\n"); yx d (dot)c (circle) 0.0 yx center (dot) radius 5
Is_in_circle – step by step printf(Enter dot\n"); scanf("%lf%lf",&d.x,&d.y); printf("Enter circle center\n"); scanf("%lf%lf",&c.center.x,&c.center.y); printf("Enter circle radius\n"); scanf("%lf",&c.radius); if (IsInCircle(&d, &c)) printf("dot is in circle\n"); else printf("dot is out of circle\n"); yx d (dot)c (circle) 0.0 yx center (dot) radius 5
Is_in_circle – step by step int IsInCircle(dot *p_dot, circle *p_circle) { double x_dist,y_dist; x_dist = p_dot->x - p_circle->center.x; y_dist = p_dot->y - p_circle->center.y; if (x_dist*x_dist + y_dist*y_dist radius*p_circle->radius) return 1; return 0; } yx (dot)(circle) 0.0 yx center (dot) radius 5 x_disty_dist …… p_circlep_dot
Is_in_circle – step by step int IsInCircle(dot *p_dot, circle *p_circle) { double x_dist,y_dist; x_dist = p_dot->x - p_circle->center.x; y_dist = p_dot->y - p_circle->center.y; if (x_dist*x_dist + y_dist*y_dist radius*p_circle->radius) return 1; return 0; } yx (dot)(circle) 0.0 yx center (dot) radius 5 x_disty_dist 1.0… p_circlep_dot
Is_in_circle – step by step int IsInCircle(dot *p_dot, circle *p_circle) { double x_dist,y_dist; x_dist = p_dot->x - p_circle->center.x; y_dist = p_dot->y - p_circle->center.y; if (x_dist*x_dist + y_dist*y_dist radius*p_circle->radius) return 1; return 0; } yx (dot)(circle) 0.0 yx center (dot) radius 5 x_disty_dist p_circlep_dot
Is_in_circle – step by step int IsInCircle(dot *p_dot, circle *p_circle) { double x_dist,y_dist; x_dist = p_dot->x - p_circle->center.x; y_dist = p_dot->y - p_circle->center.y; if (x_dist*x_dist + y_dist*y_dist radius*p_circle->radius) return 1; return 0; } yx (dot)(circle) 0.0 yx center (dot) radius 5 x_disty_dist p_circlep_dot
Is_in_circle – step by step int IsInCircle(dot *p_dot, circle *p_circle) { double x_dist,y_dist; x_dist = p_dot->x - p_circle->center.x; y_dist = p_dot->y - p_circle->center.y; if (x_dist*x_dist + y_dist*y_dist radius*p_circle->radius) return 1; return 0; } yx (dot)(circle) 0.0 yx center (dot) radius 5 x_disty_dist p_circlep_dot
Is_in_circle – step by step printf(Enter dot\n"); scanf("%lf%lf",&d.x,&d.y); printf("Enter circle center\n"); scanf("%lf%lf",&c.center.x,&c.center.y); printf("Enter circle radius\n"); scanf("%lf",&c.radius); if (IsInCircle(&d, &c)) printf("dot is in circle\n"); else printf("dot is out of circle\n"); yx d (dot)c (circle) 0.0 yx center (dot) radius 5
Exercise Write a struct that represents a date (day, month, year) Write a function that increments the date void IncDate(Date *d); For example – >
Solution IncDate.c
Exiting the program void exit(int status); Sometimes an error occurs and we want the program to immediately exit The exit function closes all open files, frees all allocated memory, and exits the program Equivalent to calling return within main Remember to #include See strcpy_with_exit.c
Structures containing arrays A structure member that is an array does not behave like an ordinary array When copying a structure that contains a member which is an array, the array is copied element by element Not just the address gets copied For example - array_member.c Reminder – ordinary arrays cant be copied simply by using the = operator They must be copied using a loop
Structures containing arrays The same happens when passing the structure to a function Changing the array inside the function wont change it in the calling function Reminder – when passing an ordinary array to a function, all that gets passed is the address of its first element Hence every change to the array within the function, changes the array in the calling function
Pointers are another matter If the member is a pointer, for example to a dynamically allocated array, all that gets copied is the pointer (the address) itself For example, pointer_member.c Hence, we should take extra care when manipulating structures that contain pointers