Passing and returning structures
Unlike arrays, a structure is copied when passed. That makes it safe, lets a function return one whole value, and occasionally makes pointers worthwhile.
After this lesson
You should be able to
- Pass a structure to a function by value and by pointer.
- Return a structure as a function's result.
- Use the arrow operator to reach a member through a pointer.
Structures are copied; arrays are not
Passing a structure copies every member, so the function cannot change the caller's copy — exactly like an int, and unlike an array. That is worth pausing on, because it means a Student containing an array behaves differently from the array on its own.
For a large structure that copy costs time. Passing a pointer avoids it, and adding const keeps the safety you gave up: const Student *s says look but do not touch.
void show(Student s) /* copy: safe, but copies everything */
{
printf("%s scored %d\n", s.name, s.marks);
}
void show_fast(const Student *s) /* no copy, still read-only */
{
printf("%s scored %d\n", s->name, s->marks);
}The arrow operator
When you hold a pointer to a structure, s->marks means the marks member of what s points at. It is shorthand for (*s).marks, and the parentheses in that longer form are compulsory because the dot binds tighter than the star.
So the rule is simple: dot for a structure, arrow for a pointer to one. Writing *s.marks is a common error and means something quite different.
Returning a whole structure
A function can return a structure by value, which is the clean way around return giving only one value — put the several answers in a structure and return that. No pointers, no output parameters.
Compare this with Unit II's divide function, which needed two pointer parameters. Returning a structure says the two results belong together, which the pointer version never states.
typedef struct {
int quotient;
int remainder;
} DivResult;
DivResult divide(int a, int b)
{
DivResult r;
r.quotient = a / b;
r.remainder = a % b;
return r; /* one value carrying two answers */
}
/* in main */
DivResult d = divide(17, 5);
printf("%d r %d\n", d.quotient, d.remainder); /* 3 r 2 */Try it yourself
Write a function that takes an array of Students and returns a structure holding both the topper and the class average.
Need a hint?
Define a second structure for the summary. It can contain a Student as a member.
Check the worked solution
Summary bundles two results that are meaningless apart, so returning one value is more honest than two output pointers. The array parameter is const because summarise only reads, while the returned Summary is a copy that stays valid after the function ends — a pointer to the local best would not.
#include <stdio.h>
typedef struct {
int roll;
char name[40];
int marks;
} Student;
typedef struct {
Student topper;
double average;
} Summary;
Summary summarise(const Student class[], int n)
{
Summary out;
int total = 0, best = 0;
for (int i = 0; i < n; i++) {
total += class[i].marks;
if (class[i].marks > class[best].marks)
best = i;
}
out.topper = class[best];
out.average = (double) total / n;
return out;
}
int main(void)
{
Student class[3] = {
{101, "Kavya", 87}, {102, "Ravi", 64}, {103, "Sneha", 91}
};
Summary s = summarise(class, 3);
printf("Topper %s with %d, average %.2f\n",
s.topper.name, s.topper.marks, s.average);
return 0;
}Quick check
Given Student *p, how do you read the marks member?
Why this lesson exists
Syllabus mapping
Structure Type Data as Input and Output Parameters · Functions with Structured Result Values
Maps to course outcomes CO4, CO5.