Menu
Coddy logo textTech

Pointer vs Value

Part of the Object Oriented Programming section of Coddy's C journey — lesson 9 of 61.

When you pass a struct to a function, C gives you two options: pass it by value (copy the entire struct) or pass it by pointer (copy just the address). The choice matters significantly for performance.

Passing by value creates a complete copy of the struct on the stack. For a small struct with a few integers, this is fine. But imagine a struct with hundreds of bytes—every function call copies all that data:

typedef struct {
    char name[100];
    int scores[50];
    double average;
} Student;

// By value: copies ~608 bytes every call
void print_by_value(Student s) {
    printf("%s: %.2f\n", s.name, s.average);
}

// By pointer: copies only 8 bytes (the address)
void print_by_pointer(const Student *s) {
    printf("%s: %.2f\n", s->name, s->average);
}

The syntax differs too. With a value parameter, you use the dot operator (s.name). With a pointer, you use the arrow operator (s->name).

The pointer version is more efficient because it only passes a memory address—typically 8 bytes regardless of struct size.

This is why C programmers almost always pass structs by pointer. Use const when the function shouldn't modify the data, and a regular pointer when it should. You get both efficiency and clear intent.

challenge icon

Challenge

Easy

Let's build a Product module that demonstrates the difference between passing structs by value and by pointer. You'll create two display functions—one that receives the entire struct as a copy, and one that receives just a pointer to it.

You'll create three files:

  • product.h: Declare a Product struct with three members: char name[50], double price, and int quantity. Also declare two functions:
    • display_by_value — takes a Product by value and prints its information
    • display_by_pointer — takes a const Product * and prints the same information
    Use include guards with the symbol PRODUCT_H.
  • product.c: Implement both functions. Notice the syntax difference: the by-value version uses the dot operator (p.name), while the pointer version uses the arrow operator (p->name). Both functions should print in the same format.
  • main.c: Create a Product, then call both display functions to show that they produce identical output despite using different parameter styles.

You will receive three inputs: the product name (a string), the price (a double), and the quantity (an integer).

In your main file, initialize a Product with these values, then call display_by_value followed by display_by_pointer.

Both functions should print in this format:

Product: {name}, Price: {price}, Qty: {quantity}

Use %.2f for the price to display two decimal places.

For example, with inputs Laptop, 999.99, and 5, the output would be:

Product: Laptop, Price: 999.99, Qty: 5
Product: Laptop, Price: 999.99, Qty: 5

Cheat sheet

When passing structs to functions, you can choose between passing by value (copying the entire struct) or passing by pointer (copying only the address).

Passing by value creates a complete copy of the struct:

void print_by_value(Student s) {
    printf("%s: %.2f\n", s.name, s.average);  // Use dot operator
}

Passing by pointer passes only the memory address:

void print_by_pointer(const Student *s) {
    printf("%s: %.2f\n", s->name, s->average);  // Use arrow operator
}

Key differences:

  • By value uses the dot operator (s.member)
  • By pointer uses the arrow operator (s->member)
  • Pointers are more efficient for large structs (only 8 bytes vs. entire struct size)
  • Use const with pointers when the function shouldn't modify the data

C programmers typically prefer passing structs by pointer for better performance.

Try it yourself

#include <stdio.h>
#include <string.h>
#include "product.h"

int main() {
    char name[50];
    double price;
    int quantity;
    
    // Read inputs
    scanf("%s", name);
    scanf("%lf", &price);
    scanf("%d", &quantity);
    
    // TODO: Create a Product variable and initialize it with the input values
    // Hint: Use strcpy to copy the name into the struct's name field
    
    // TODO: Call display_by_value with the Product
    
    // TODO: Call display_by_pointer with a pointer to the Product
    
    return 0;
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Object Oriented Programming