HomebaseWorks
Lesson 4 of 4

Structs and passing data to functions

Define and copy structs, pass them by value or by pointer, understand why arrays decay inside functions, and return heap memory safely.

EWritten by the HomebaseWorks editorial team · reviewed 26 Oct 2026

Real C programs group related fields into structs and pass them between functions, and screenings test whether you understand what gets copied, what gets shared, and what the callee can actually see. The rules are mechanical, and this lesson walks through them with runnable examples.

Advertisement

Defining and copying a struct

struct Point {
    int x;
    int y;
};
typedef struct {
    char name[32];
    int qty;
    double price;
} Item;

struct Point p = {3, 4};
Item it = {"pen", 10, 2.5};
Item copy = it;                /* field-by-field copy */
strcpy(copy.name, "ink");
printf("%s %s\n", it.name, copy.name);   /* pen ink */

Assignment copies the whole struct, including a character array inside it, so it is untouched. typedef just saves you from writing struct every time. You cannot compare two structs with ==; compare the fields you care about or use memcmp with care.

By value versus by pointer

void move_copy(struct Point p) { p.x = 100; }    /* changes a copy */
void move_ptr(struct Point *p) { p->x = 100; }   /* changes the caller's struct */

move_copy(p);
printf("%d\n", p.x);     /* 3 */
move_ptr(&p);
printf("%d\n", p.x);     /* 100 */

C always passes by value. To let a function modify the caller's struct, pass its address and use ->. Passing a pointer also avoids copying large structs; add const when the function only reads, which documents intent and lets the compiler catch accidental writes.

Arrays decay, and returning memory

int sum(int arr[], int n) {          /* arr is really int * */
    int s = 0;
    for (int i = 0; i < n; i++) s += arr[i];
    return s;
}
size_t bad_len(int arr[]) { return sizeof(arr); }   /* size of a pointer */

int nums[] = {1, 2, 3, 4};
printf("%d\n", sum(nums, 4));       /* 10 */
printf("%zu\n", bad_len(nums));     /* 8 on a 64-bit system, not 16 */

An array argument becomes a pointer to its first element, so the length must travel as a separate parameter. Returning the address of a local variable is a classic bug, because the local dies when the function returns; return malloc memory instead and make the caller free it, or let the caller pass a buffer in.

Common mistakes and a practice habit

  • Using . on a pointer or -> on a plain struct.
  • Using sizeof on an array parameter to find its length.
  • Returning a pointer to a local array.

Practice habit: Pick a real record from your work, such as an invoice line or a sensor reading, define it as a struct, and write three functions: one that fills it through a pointer, one that reads it through a const pointer, and one that sums an array of them. Compile with warnings on and run it. Repeat with a new record each week.

Advertisement
Continue with C4 lessons · 1 interview set · 1 test · 1 certificate
Not tested

More in Programming