C++: Practice: Functions Comprehensive
Last updated: 2026-08-26
Previous lessons covered various aspects of functions separately, but in real programs they are used together.
In this lesson, we'll practice making functions work together through several comprehensive examples.
1. Example 1: Simple Math Utility Library
(1) 1.1 Requirements Analysis
We'll build a math utility library with the following functions:
int add(int a, int b)— Additionint subtract(int a, int b)— Subtractionint multiply(int a, int b)— Multiplicationdouble divide(int a, int b)— Division (returns floating point)int power(int base, int exp)— Exponentiationbool isPrime(int n)— Prime check
▶ Example 1: Math Utility Library (Difficulty ⭐⭐)
#include <iostream>
#include <cmath>
// Function prototypes
int add(int a, int b);
int subtract(int a, int b);
int multiply(int a, int b);
double divide(int a, int b);
int power(int base, int exp);
bool isPrime(int n);
int main() {
int x = 10, y = 3;
std::cout << "x + y = " << add(x, y) << std::endl;
std::cout << "x - y = " << subtract(x, y) << std::endl;
std::cout << "x * y = " << multiply(x, y) << std::endl;
std::cout << "x / y = " << divide(x, y) << std::endl;
std::cout << "x ^ y = " << power(x, y) << std::endl;
std::cout << "Is x prime? " << (isPrime(x) ? "Yes" : "No") << std::endl;
return 0;
}
// Function definitions
int add(int a, int b) {
return a + b;
}
int subtract(int a, int b) {
return a - b;
}
int multiply(int a, int b) {
return a * b;
}
double divide(int a, int b) {
if (b == 0) {
return 0.0;
}
return static_cast<double>(a) / b;
}
int power(int base, int exp) {
if (exp < 0) {
return 0; // Simplified: negative exponents not supported
}
int result = 1;
for (int i = 0; i < exp; i++) {
result *= base;
}
return result;
}
bool isPrime(int n) {
if (n <= 1) {
return false;
}
for (int i = 2; i * i <= n; i++) {
if (n % i == 0) {
return false;
}
}
return true;
}
Output:
x + y =
x - y =
x * y =
x / y =
x ^ y =
Is x prime? YesNo
Sample run:
x + y = 13
x - y = 7
x * y = 30
x / y = 3.33333
x ^ y = 1000
Is x prime? No
2. Example 2: Number Guessing Game (Function Version)
(1) 2.1 Requirements Analysis
Rewrite the previous number guessing game using functions:
void printWelcome()— Print welcome messageint getSecretNumber()— Generate secret numberint getGuess()— Get user's guessvoid printResult(int guess, int secretNumber)— Print result (too high/too low/correct)void playGame()— Main game logic
▶ Example 2: Number Guessing Game (Function Version) (Difficulty ⭐⭐)
#include <iostream>
#include <cstdlib>
#include <ctime>
// Function prototypes
void printWelcome();
int getSecretNumber();
int getGuess();
void printResult(int guess, int secretNumber);
void playGame();
int main() {
std::srand(static_cast<unsigned int>(std::time(nullptr)));
char playAgain;
do {
playGame();
std::cout << "Want to play again? (y/n): ";
std::cin >> playAgain;
} while (playAgain == 'y' || playAgain == 'Y');
std::cout << "Thanks for playing, goodbye!" << std::endl;
return 0;
}
// Function definitions
void printWelcome() {
std::cout << "=========== Number Guessing Game ===========" << std::endl;
std::cout << "I'm thinking of a number from 1-100, guess it!" << std::endl << std::endl;
}
int getSecretNumber() {
return std::rand() % 100 + 1;
}
int getGuess() {
int guess;
std::cout << "Enter your guess: ";
std::cin >> guess;
return guess;
}
void printResult(int guess, int secretNumber) {
if (guess > secretNumber) {
std::cout << "Too high! Try again." << std::endl;
} else if (guess < secretNumber) {
std::cout << "Too low! Try again." << std::endl;
} else {
std::cout << "🎉 Congratulations! You got it!" << std::endl;
}
}
void playGame() {
printWelcome();
int secretNumber = getSecretNumber();
int guess;
int attempts = 0;
do {
guess = getGuess();
attempts++;
printResult(guess, secretNumber);
} while (guess != secretNumber);
std::cout << "You guessed " << attempts << " times." << std::endl << std::endl;
}
Output:
Want to play again? (y/n):
Thanks for playing, goodbye!
=========== Number Guessing Game ===========
I'm thinking of a number from 1-100, guess it!
Enter your guess:
Too high! Try again.
Too low! Try again.
🎉 Congratulations! You got it!
You guessed times.
3. Example 3: Simple Calculator (Function Overloading Version)
(1) 3.1 Requirements Analysis
Implement a calculator using function overloading, supporting both int and double types.
▶ Example 3: Calculator (Function Overloading Version) (Difficulty ⭐⭐)
#include <iostream>
#include <iomanip>
// Function prototypes (overloaded)
int calculate(int a, int b, char op);
double calculate(double a, double b, char op);
int main() {
int intResult = calculate(10, 3, '+');
double doubleResult = calculate(10.0, 3.0, '/');
std::cout << "10 + 3 = " << intResult << std::endl;
std::cout << std::fixed << std::setprecision(2);
std::cout << "10.0 / 3.0 = " << doubleResult << std::endl;
return 0;
}
// Function definitions (overloaded)
int calculate(int a, int b, char op) {
switch (op) {
case '+': return a + b;
case '-': return a - b;
case '*': return a * b;
case '/': return a / b; // Integer division
default: return 0;
}
}
double calculate(double a, double b, char op) {
switch (op) {
case '+': return a + b;
case '-': return a - b;
case '*': return a * b;
case '/': return b != 0 ? a / b : 0.0;
default: return 0.0;
}
}
Output:
10 + 3 =
10.0 / 3.0 =
4. Practice Exercise: Student Grade Management (Function Version)
▶ Example 4: Student Grade Management (Difficulty ⭐⭐⭐)
#include <iostream>
#include <string>
// Function prototypes
void printMenu();
void addStudent(std::string names[], int scores[], int& count);
void printStudents(const std::string names[], const int scores[], int count);
double calculateAverage(const int scores[], int count);
int findMaxScore(const int scores[], int count);
int main() {
const int MAX_STUDENTS = 100;
std::string names[MAX_STUDENTS];
int scores[MAX_STUDENTS];
int count = 0;
int choice;
do {
printMenu();
std::cout << "Choose (1-4): ";
std::cin >> choice;
if (choice == 1) {
addStudent(names, scores, count);
} else if (choice == 2) {
printStudents(names, scores, count);
} else if (choice == 3) {
if (count == 0) {
std::cout << "No student data!" << std::endl;
} else {
std::cout << "Average: " << calculateAverage(scores, count) << std::endl;
std::cout << "Highest score: " << findMaxScore(scores, count) << std::endl;
}
} else if (choice == 4) {
std::cout << "Goodbye!" << std::endl;
} else {
std::cout << "Error: Please enter a number between 1-4!" << std::endl;
}
std::cout << std::endl;
} while (choice != 4);
return 0;
}
// Function definitions
void printMenu() {
std::cout << "=========== Student Grade Management ===========" << std::endl;
std::cout << "1. Add student" << std::endl;
std::cout << "2. Show all students" << std::endl;
std::cout << "3. Statistics" << std::endl;
std::cout << "4. Exit" << std::endl;
}
void addStudent(std::string names[], int scores[], int& count) {
if (count >= 100) {
std::cout << "Maximum number of students reached!" << std::endl;
return;
}
std::cout << "Enter name: ";
std::cin.ignore();
std::getline(std::cin, names[count]);
std::cout << "Enter score: ";
std::cin >> scores[count];
count++;
std::cout << "Added successfully!" << std::endl;
}
void printStudents(const std::string names[], const int scores[], int count) {
if (count == 0) {
std::cout << "No student data!" << std::endl;
return;
}
std::cout << "=========== Student List ==========" << std::endl;
for (int i = 0; i < count; i++) {
std::cout << i + 1 << ". " << names[i] << " - " << scores[i] << std::endl;
}
}
double calculateAverage(const int scores[], int count) {
if (count == 0) {
return 0.0;
}
int sum = 0;
for (int i = 0; i < count; i++) {
sum += scores[i];
}
return static_cast<double>(sum) / count;
}
int findMaxScore(const int scores[], int count) {
if (count == 0) {
return 0;
}
int maxScore = scores[0];
for (int i = 1; i < count; i++) {
if (scores[i] > maxScore) {
maxScore = scores[i];
}
}
return maxScore;
}
Output:
Choose (1-4):
No student data!
Average:
Highest score:
Goodbye!
Error: Please enter a number between 1-4!
=========== Student Grade Management ===========
1. Add student
2. Show all students
3. Statistics
4. Exit
Maximum number of students reached!
Enter name:
Enter score:
Added successfully!
No student data!
=========== Student List ==========
. -
❓ FAQ
main, you don't need a prototype.📖 Summary
- In real programs, functions work together
- Break big problems into small functions, each doing one thing
- Use function prototypes for declarations, function definitions for implementation
- Function overloading allows same-named functions to handle different types
- Good function naming makes code self-documenting
📝 Exercises
-
Basic (Difficulty ⭐): Rewrite the previous "calculate rectangle area" program as a function version:
- Write a function
double calculateArea(double width, double height) - Call it in
main
- Write a function
-
Intermediate (Difficulty ⭐⭐): Write a program with the following functions: 3.
int fibonacci(int n)— Returns the nth Fibonacci number 4.void printFibonacci(int n)— Prints the first n terms 5. Inmain, let the user input n and call these two functions -
Challenge (Difficulty ⭐⭐⭐): Extend the "Student Grade Management" program with the following features: 6. Delete student (by name or index) 7. Sort by grade (high to low) 8. Save to file / Load from file (optional)
- Function encapsulation improves code readability and reusability
- Arrays decay to pointers when passed as function parameters
- Function composition: one function calling another
- Common recursive applications: factorial, Fibonacci, exponentiation
- Program architecture: input → processing → output, each step encapsulated in a function
5. 🚀 Next Steps
Congratulations! You've completed all lessons in Phase 2 (Functions). Next, we enter Phase 3 (Arrays, Strings, Structs), learning how to handle multiple values of the same type and C++ strings.