An entire structure can be passed to a function as its parameter so that the function can process an entire record and return some result. For instance, you could pass a student record to a function which in turn would compute the average of marks obtained in all subjects in all the semesters and return the aggregate grade.
A structure can be transferred to a function either using call by value or call by reference scheme.
Remember that C only implements call by value scheme of parameter transmission. Call by reference is indirectly implemented by passing address of variable.
A function can also return an instance of a structure using the return statement. Though all compilers may not support this. Hence, you should avoid returning a complete structure from a function. If the function has to alter the data stored in the structure, it would be better to pass the address of the structure variable. The function can then work on the members of the passed structure using pointers.
A typical usage of passing structure to a function is illustrated in the below example.
#include <stdio.h>struct name { char first_name[21]; char middle_name[21]; char last_name[21];};typedef struct { int enrolment_no; struct name stud_name; char course_name[41]; float module_marks[4]; char grade;} student;main(){ void read_student(student *); static student a = {1234, "Sunidhi", "Narayan", "Mishra", "Arts", 45, 78, 98, 67, 'A'}; /* Print initialized student data */ printf("\nEnrollment No: %d\nFirst Name: %s\nMiddle Name : %s\nLast Name: %s\nCourse Name: %s\nGrade: %c\n", a.enrolment_no, a.stud_name.first_name, a.stud_name.middle_name, a.stud_name.last_name, a.course_name, a.grade); /*Function call to read student data inputted by user */ read_student(&a); /* Print user provided student data */ printf("\nEnrollment No: %d\nFirst Name: %s\nMiddle Name : %s\nLast Name: %s\nCourse Name: %s\nGrade: %c\n", a.enrolment_no, a.stud_name.first_name, a.stud_name.middle_name, a.stud_name.last_name, a.course_name, a.grade);}void read_student(student *a) { printf("\nEnrollment No.: "); scanf("%d", &a->enrolment_no); fflush(stdin); printf("\nFirst Name: "); gets(a->stud_name.first_name); printf("\nMiddle Name: "); gets(a->stud_name.middle_name); printf("\nLast Name: "); gets(a->stud_name.last_name); printf("\nCourse: "); gets(a->course_name); printf("\nMarks (comma separated 4 marks): "); scanf("%f, %f, %f, %f", &a->module_marks[0], &a->module_marks[1], &a->module_marks[2], &a->module_marks[3]); fflush(stdin); printf("\nGrade: "); scanf("%c", &a->grade); fflush(stdin); return;}
A structure can be transmitted to another function using a pointer which as we have seen above implements the call by reference scheme. The address of the structure transmitted by the calling function is received in the called function in a pointer to the same type of structure. In the called function, the individual structure members are accessed by the pointer variable using the notation, ps->name or (*ps).name.
Let us look at another example.
#include <stdio.h>typedef struct {float real;float imag;} complex; complex add_complex(complex, complex, complex *);void read_complex(complex *);void write_complex(complex);main() { complex a, b, c;read_complex(&a);read_complex(&b);add_complex(a, b, &c);write_complex(c);}complex add_complex(complex x, complex y, complex *tot){tot->real = x.real + y.real;tot->imag = x.imag + y.imag;return;}void read_complex(complex *x){printf("\nEnter the real and imaginary components of the complex number: ");scanf("%f %f", &(x->real), &(x->imag));}void write_complex(complex x){char c[3] = "+j";if(x.imag < 0){c[0] = '-';x.imag = -x.imag;}printf("Resultant Complex Number = %.2f%s%.2f", x.real, c, x.imag);}
Exercises
For each of following C programs, describe the output that will be generated.
#include<stdio.h>typedef struct {char *x;char *y;char *z;} planets;main(){void f(planets sample);static planets sample = {"earth", "mars", "jupiter"};printf("%s %s %s \n", sample.x, sample.y, sample.z);f(sample);printf("%s %s %s \n", sample.x, sample.y, sample.z);}void f(planets sample){sample.x = "mercury";sample.y = "venus";sample.z = "saturn";printf("%s %s %s \n", sample.x, sample.y, sample.z);return;}
#include <stdio.h>typedef struct{char *x;char *y;char *z;} planets;main(){void f(planets *);static planets sample = {"earth", "mars", "Jupiter"};printf("%s %s %s\n", sample.x, sample.y, sample.z);f(&sample);printf("%s %s %s\n", sample.x, sample.y, sample.z);}void f(planets *sample){sample->x = "mercury";sample->y = "venus";sample->z = "saturn";printf("%s %s %s\n", sample->x, sample->y, sample->z);return;}
#include <stdio.h>typedef union {int a;float b;} sample;main(){sample u;void f(sample *);u.a = 20;u.b = 1.6;printf("%d, %f\n", u.a, u.b);f(&u);printf("%d %f\n", u.a, u.b);}void f(sample *x){x->a = 500;printf("%d %f\n", x->a, x->b);return;}
In the above code, ask yourself - why is arbitrary value printed for one of the elements of the union.
Share: