← Back to C Course | Chapter 8: Structures & Unions | Lesson 3 of 7

C Structure & Functions

Passing a structure to a function can be done by copying it or by giving its address, like handing over a photocopy or the original paper. Copies leave the original unchanged.
Syntax
c
return_type function_name(struct StructName s);   // by value (copy)
return_type function_name(struct StructName *s);  // by pointer

function_name(variable_name);
function_name(&variable_name);

Passing Structures by Value

This mirrors how any variable is passed by value in C by default -- the function receives its own independent copy of every member, so it's safe from accidental modification but also can't report changes back to the caller.

Example: Passing Structures by Value

c
// Include standard input/output (printf, scanf)
#include <stdio.h>
// Define a structure type named Student
struct Student { int age; };
void tryChange(struct Student s) {
	s.age = 99;
}
// Program execution starts in main()
int main() {
	struct Student s = {20};
	tryChange(s);
	// Print formatted text to the screen
	printf("%d", s.age);
	// Return 0 to signal that the program finished successfully
	return 0;
}

Passing Structures by Reference

Passing a pointer (like void update(struct Student *s)) avoids copying potentially large amounts of data on every function call, and is the standard approach once a structure has more than a couple of small fields.

Example: Passing Structures by Reference

c
// Include standard input/output (printf, scanf)
#include <stdio.h>
// Define a structure type named Student
struct Student { int age; };
void update(struct Student *s) {
	s->age = 21;
}
// Program execution starts in main()
int main() {
	struct Student s = {20};
	update(&s);
	// Print formatted text to the screen
	printf("%d", s.age);
	// Return 0 to signal that the program finished successfully
	return 0;
}

Modifying Structures in Functions

Inside the function, you use the arrow operator (s->name = "Bob") to modify fields through the pointer -- this directly changes the original structure the caller passed in, unlike the pass-by-value approach.

Example: Modifying Structures in Functions

c
// Include standard input/output (printf, scanf)
#include <stdio.h>
// Define a structure type named Student
struct Student { char name[20]; };
void rename2(struct Student *s) {
	s->name[0] = 'B';
}
// Program execution starts in main()
int main() {
	struct Student s = {"Ann"};
	rename2(&s);
	// Print formatted text to the screen
	printf("%s", s.name);
	// Return 0 to signal that the program finished successfully
	return 0;
}

Returning Structures from Functions

A function like struct Point makePoint(int x, int y) { struct Point p = {x, y}; return p; } builds and hands back a fully-formed structure, which is a clean way to construct complex data without needing an out-parameter.

Example: Returning Structures from Functions

c
// Include standard input/output (printf, scanf)
#include <stdio.h>
// Define a structure type named Point
struct Point { int x, y; };
struct Point makePoint(int x, int y) {
	struct Point p = {x, y};
	// Send p back to the caller
	return p;
}
// Program execution starts in main()
int main() {
	struct Point p = makePoint(3, 4);
	// Print formatted text to the screen
	printf("%d %d", p.x, p.y);
	// Return 0 to signal that the program finished successfully
	return 0;
}

Comparing Performance

For a structure with many members or large arrays inside it, copying by value on every function call adds up -- profiling real programs shows pointer-passing is almost always faster once a structure grows beyond a few small fields.

Example: Comparing Performance

c
// Include standard input/output (printf, scanf)
#include <stdio.h>
// Define a structure type named Big
struct Big { int data[100]; };
void byRef(struct Big *b) {
	b->data[0] = 1;
}
// Program execution starts in main()
int main() {
	struct Big b = {0};
	byRef(&b);
	// Print formatted text to the screen
	printf("%d", b.data[0]);
	// Return 0 to signal that the program finished successfully
	return 0;
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Modifying a struct passed by value and expecting the caller's copy to change.
  2. Passing a large struct by value each time, which copies all of it and slows the program.
  3. Returning a pointer to a local struct, which no longer exists after the function ends.
🔒

Chapter Quiz — Complete all 7 topics to unlock

0/7 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.