Menu
Coddy logo textTech

Passing Struct Pointers

Part of the Logic & Flow section of Coddy's C journey — lesson 47 of 63.

While passing structs by value works well for reading data, it becomes inefficient with large structs because the entire structure gets copied. More importantly, you can't modify the original struct from within the function. This is where passing pointers to structs becomes essential.

When you pass a pointer to a struct instead of the struct itself, the function receives the memory address of the original struct. This approach offers two key advantages: it's more efficient (no copying) and allows the function to modify the original data.

The syntax for a function that accepts a pointer to a struct is:

void functionName(struct StructureName *ptr) {
    // Function body using ptr->member
}

Inside the function, you use the arrow operator to access and modify the struct members. Any changes made through the pointer will directly affect the original struct in the calling function, making this approach perfect for functions that need to update or transform struct data.

This technique is fundamental for building efficient C programs that work with complex data structures, as it combines the power of pointers with the organization of structs.

challenge icon

Challenge

Easy

Create a C program that demonstrates passing pointers to structs to functions for efficient data modification. Your program should:

  1. Define a struct named BankAccount with the following members:
    • An integer accountNumber to store the account number
    • A character array ownerName with size 30 to store the account owner's name
    • A float balance to store the account balance
    • An integer transactionCount to store the number of transactions
  2. Write a function named depositMoney that:
    • Takes a pointer to a BankAccount struct and a float amount as parameters
    • Adds the amount to the account balance using the arrow operator
    • Increments the transaction count by 1
    • Prints Deposit successful. New balance: [balance]
  3. Write a function named withdrawMoney that:
    • Takes a pointer to a BankAccount struct and a float amount as parameters
    • Checks if the withdrawal amount is greater than the current balance
    • If insufficient funds, prints Insufficient funds. Current balance: [balance]
    • If sufficient funds, subtracts the amount from the balance, increments the transaction count, and prints Withdrawal successful. New balance: [balance]
  4. Write a function named displayAccount that:
    • Takes a pointer to a BankAccount struct as a parameter
    • Prints the account information in this exact format:
      • Account Information:
      • Account Number: [accountNumber]
      • Owner: [ownerName]
      • Balance: [balance]
      • Transactions: [transactionCount]
  5. In the main function:
    • Create a BankAccount variable named account
    • Read the account number, owner name, and initial balance from input
    • Set the transaction count to 0
    • Call displayAccount to show the initial account state
    • Read a deposit amount and call depositMoney
    • Read a withdrawal amount and call withdrawMoney
    • Call displayAccount to show the final account state

This challenge demonstrates the power of passing pointers to structs to functions. Unlike pass-by-value, the functions receive the memory address of the original struct, allowing them to directly modify the original data. This approach is more efficient (no copying) and enables functions to permanently change struct values in the calling function.

Cheat sheet

When passing structs by value, the entire structure gets copied, which is inefficient for large structs and prevents modifying the original data. Passing pointers to structs solves both issues by passing the memory address instead.

Function syntax for accepting a pointer to a struct:

void functionName(struct StructureName *ptr) {
    // Function body using ptr->member
}

Inside the function, use the arrow operator (->) to access and modify struct members through the pointer. Any changes made will directly affect the original struct in the calling function.

This approach offers two key advantages:

  • More efficient (no copying of the entire struct)
  • Allows functions to modify the original struct data

Try it yourself

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

// TODO: Define the BankAccount struct here

// TODO: Write the depositMoney function here

// TODO: Write the withdrawMoney function here

// TODO: Write the displayAccount function here

int main() {
    // Read input
    int accountNum;
    char ownerName[30];
    float initialBalance;
    float depositAmount;
    float withdrawAmount;
    
    scanf("%d", &accountNum);
    scanf("%s", ownerName);
    scanf("%f", &initialBalance);
    scanf("%f", &depositAmount);
    scanf("%f", &withdrawAmount);
    
    // TODO: Create BankAccount variable and initialize it
    
    // TODO: Call displayAccount to show initial state
    
    // TODO: Call depositMoney with deposit amount
    
    // TODO: Call withdrawMoney with withdrawal amount
    
    // TODO: Call displayAccount to show final state
    
    return 0;
}
quiz iconTest yourself

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

All lessons in Logic & Flow