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
EasyCreate a C program that demonstrates passing pointers to structs to functions for efficient data modification. Your program should:
- Define a
structnamedBankAccountwith the following members:- An integer
accountNumberto store the account number - A character array
ownerNamewith size 30 to store the account owner's name - A float
balanceto store the account balance - An integer
transactionCountto store the number of transactions
- An integer
- Write a function named
depositMoneythat:- Takes a pointer to a
BankAccountstruct 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]
- Takes a pointer to a
- Write a function named
withdrawMoneythat:- Takes a pointer to a
BankAccountstruct 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]
- Takes a pointer to a
- Write a function named
displayAccountthat:- Takes a pointer to a
BankAccountstruct as a parameter - Prints the account information in this exact format:
Account Information:Account Number: [accountNumber]Owner: [ownerName]Balance: [balance]Transactions: [transactionCount]
- Takes a pointer to a
- In the main function:
- Create a
BankAccountvariable namedaccount - Read the account number, owner name, and initial balance from input
- Set the transaction count to 0
- Call
displayAccountto show the initial account state - Read a deposit amount and call
depositMoney - Read a withdrawal amount and call
withdrawMoney - Call
displayAccountto show the final account state
- Create a
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;
}This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Logic & Flow
1Pointers Fundamentals
What is a Pointer?Declaring PointersThe Address-Of Operator (&)The Dereference Operator (*)NULL PointersRecap: Pointer Basics4Project: Simple Text Utility
Project OverviewCounting Characters2Pointers and Arrays
Array Names as PointersArray Elements - PointersPointer ArithmeticComparing PointersRecap: Pointer Array Traversal5Pointers and Functions
Pass-by-ValuePassing Pointers to FunctionsModifying Vars via PointersA Classic Example: SwapPassing Arrays to FunctionsRecap: Function Pointer Args8Structs and Pointers
Pointers to StructsThe Arrow Operator (->)Passing Structs by ValuePassing Struct PointersDynamic Allocation of StructsRecap: Modifying Struct - Ptr11Final Recap Challenges
Recap: Dynamic String ConcatRecap: Array of StructsRecap: Word Frequency Counter3Character Arrays and Strings
Strings as char ArraysThe Null TerminatorString Input with scanfUsing strlen()Using strcpy()Using strcat()Using strcmp()Recap: Basic String Functions