Backend Systemsbeginner
C Functions, Structs & Arrays
Master C functions, parameter passing, structs, typedef, and arrays. Learn how C organizes code and data before introducing pointers.
Asma HafeezApril 17, 20265 min read
cfunctionsstructsarraystypedef
C Functions, Structs & Arrays
Functions let you organize code into reusable units. Structs let you group related data together. Together they're the building blocks of C programs before you reach pointers.
Functions
C
#include <stdio.h>
// Declaration (prototype) — tells the compiler the function exists
int add(int a, int b);
// Definition
int add(int a, int b) {
return a + b;
}
// Void function — returns nothing
void greet(const char* name) {
printf("Hello, %s!\n", name);
}
int main(void) {
int result = add(3, 4); // 7
greet("Alice"); // Hello, Alice!
return 0;
}Pass by Value
C passes arguments by value — the function gets a copy.
C
void double_it(int n) {
n = n * 2; // modifies the local copy only
}
int x = 5;
double_it(x);
printf("%d\n", x); // 5 — unchanged!To modify the original, use pointers (covered in the next lesson).
Function Prototypes
Declare functions before main or in a header file.
C
// math_utils.h — header file
#ifndef MATH_UTILS_H
#define MATH_UTILS_H
int max(int a, int b);
double power(double base, int exp);
int is_prime(int n);
#endifC
// math_utils.c — implementation
#include "math_utils.h"
int max(int a, int b) { return a > b ? a : b; }
double power(double base, int exp) {
double result = 1.0;
for (int i = 0; i < exp; i++) result *= base;
return result;
}
int is_prime(int n) {
if (n < 2) return 0;
for (int i = 2; i * i <= n; i++) {
if (n % i == 0) return 0;
}
return 1;
}Structs — Group Related Data
C
// Define a struct type
struct Point {
double x;
double y;
};
// Use it
struct Point p1;
p1.x = 3.0;
p1.y = 4.0;
// Initialize with a literal
struct Point p2 = {6.0, 8.0};
struct Point origin = {.x = 0.0, .y = 0.0}; // designated initializers
// Access members
printf("(%f, %f)\n", p1.x, p1.y);typedef — Cleaner Syntax
C
typedef struct {
double x;
double y;
} Point; // now use just "Point" instead of "struct Point"
Point p = {3.0, 4.0};
// Functions with structs (passed by value — copy)
double distance(Point a, Point b) {
double dx = a.x - b.x;
double dy = a.y - b.y;
return sqrt(dx * dx + dy * dy); // #include <math.h>
}
double d = distance(p, origin);Nested Structs
C
typedef struct {
char first[50];
char last[50];
} Name;
typedef struct {
Name name;
int age;
double salary;
} Employee;
Employee emp = {
.name = {.first = "Alice", .last = "Smith"},
.age = 30,
.salary = 85000.0
};
printf("Name: %s %s, Age: %d\n",
emp.name.first, emp.name.last, emp.age);Arrays of Structs
C
#define MAX_STUDENTS 100
typedef struct {
char name[50];
int id;
double gpa;
} Student;
Student class[MAX_STUDENTS];
int count = 0;
// Add students
void add_student(const char* name, int id, double gpa) {
if (count >= MAX_STUDENTS) return;
// strncpy is safer than strcpy
strncpy(class[count].name, name, sizeof(class[count].name) - 1);
class[count].name[sizeof(class[count].name) - 1] = '\0';
class[count].id = id;
class[count].gpa = gpa;
count++;
}
// Print all students
void print_students(void) {
for (int i = 0; i < count; i++) {
printf("ID: %d | %-20s | GPA: %.2f\n",
class[i].id, class[i].name, class[i].gpa);
}
}
// Find student by ID
int find_student(int id) {
for (int i = 0; i < count; i++) {
if (class[i].id == id) return i; // return index
}
return -1; // not found
}Variable-Length Logic with Arrays
C
// Compute sum and average of an array
double sum_array(const double* arr, int n) {
double total = 0.0;
for (int i = 0; i < n; i++) {
total += arr[i];
}
return total;
}
double average(const double* arr, int n) {
if (n == 0) return 0.0;
return sum_array(arr, n) / n;
}
// Bubble sort
void sort_int_array(int* arr, int n) {
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
double grades[] = {85.5, 92.0, 78.3, 90.0, 88.5};
int n = sizeof(grades) / sizeof(grades[0]);
printf("Average: %.2f\n", average(grades, n));Enums
C
typedef enum {
PENDING,
ACTIVE,
INACTIVE,
DELETED
} AccountStatus;
typedef struct {
int id;
char owner[50];
double balance;
AccountStatus status;
} Account;
const char* status_to_string(AccountStatus s) {
switch (s) {
case PENDING: return "Pending";
case ACTIVE: return "Active";
case INACTIVE: return "Inactive";
case DELETED: return "Deleted";
default: return "Unknown";
}
}
Account acc = {1, "Alice", 1000.0, ACTIVE};
printf("Account #%d (%s): $%.2f [%s]\n",
acc.id, acc.owner, acc.balance, status_to_string(acc.status));Function Pointers
C
// A function pointer type: int (*fn)(int, int)
typedef int (*BinaryOp)(int, int);
int add(int a, int b) { return a + b; }
int sub(int a, int b) { return a - b; }
int mul(int a, int b) { return a * b; }
// Apply any operation
int apply(BinaryOp op, int x, int y) {
return op(x, y);
}
printf("%d\n", apply(add, 3, 4)); // 7
printf("%d\n", apply(mul, 3, 4)); // 12
// Array of function pointers (dispatch table)
BinaryOp ops[] = {add, sub, mul};
const char* names[] = {"add", "sub", "mul"};
for (int i = 0; i < 3; i++) {
printf("%s(10, 3) = %d\n", names[i], ops[i](10, 3));
}Key Takeaways
- C passes arguments by value — functions receive copies; use pointers to modify originals
- Always use header guards (
#ifndef) in.hfiles to prevent double-inclusion typedef structremoves the need to writestructevery time- Pass the length alongside arrays to functions — arrays don't carry their size
- Function pointers enable polymorphism and callbacks in C — essential for sorting and event systems
Enjoyed this article?
Explore the Backend Systems learning path for more.
Found this helpful?
Leave a comment
Have a question, correction, or just found this helpful? Leave a note below.