All C++ Exercises
Print your name and age with variables
Description: Create a std::string for your name and an int for your age. Print My name is Riya and I am 21 years old. with your own values.
Hint:
- Join the parts with
<<onstd::cout.
Solution
#include <iostream>
#include <print>
#include <string>
int main() {
std::string name = "Riya";
int age = 21;
std::cout << "My name is " << name << " and I am " << age << " years old.\n";
std::println("My name is {} and I am {} years old.", name, age);
}
My name is Riya and I am 21 years old.
My name is Riya and I am 21 years old.
How it works
<<sends each part to the output stream, one after the other.std::println(C++23) uses{}placeholders.
Read C++ Variables.
Swap two numbers using a reference function
Description: Write a function swap_values(int& a, int& b) which swaps two variables. Test it with 10 and 25, and compare it with std::swap.
Hint:
- A reference parameter works on the original variable.
Solution
#include <iostream>
#include <utility>
void swap_values(int& a, int& b) {
int temp = a;
a = b;
b = temp;
}
int main() {
int x = 10, y = 25;
swap_values(x, y);
std::cout << x << ' ' << y << '\n';
std::swap(x, y);
std::cout << x << ' ' << y << '\n';
}
25 10
10 25
How it works
- Because the parameters are references, the function changes
xandyof main, not copies.
Read C++ References.
Convert Celsius to Fahrenheit
Description: Convert 0, 37 and 100 degrees Celsius to Fahrenheit with F = C * 9 / 5 + 32, and print one digit after the decimal point.
Hint:
- Use
doubleand9.0 / 5.
Solution
#include <print>
double to_fahrenheit(double c) {
return c * 9.0 / 5 + 32;
}
int main() {
for (double c : {0.0, 37.0, 100.0}) {
std::println("{:.1f} C = {:.1f} F", c, to_fahrenheit(c));
}
}
0.0 C = 32.0 F
37.0 C = 98.6 F
100.0 C = 212.0 F
How it works
9.0 / 5is a decimal division.9 / 5would be 1 (integer division).{:.1f}prints one digit after the point.
Read C++ Functions.
Find the largest of three numbers
Description: Write largest(int a, int b, int c). Test with (12, 45, 30) and (7, 7, 3).
Hint:
- Compare with
>=and&&, or callstd::maxwith a list.
Solution
#include <algorithm>
#include <iostream>
int largest(int a, int b, int c) {
if (a >= b && a >= c) return a;
if (b >= c) return b;
return c;
}
int main() {
std::cout << largest(12, 45, 30) << '\n';
std::cout << largest(7, 7, 3) << '\n';
std::cout << std::max({12, 45, 30}) << '\n'; // the library way
}
45
7
45
How it works
- If
ais not the biggest, the answer isborc, so one more check is enough.
Read C++ if else.
Check if a year is a leap year
Description: Write is_leap(int year). Test 1900, 2000, 2024 and 2026.
Hint:
- Use
%and the three rules.
Solution
#include <iostream>
bool is_leap(int year) {
return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
}
int main() {
std::cout << std::boolalpha;
for (int y : {1900, 2000, 2024, 2026}) {
std::cout << y << " -> " << is_leap(y) << '\n';
}
}
1900 -> false
2000 -> true
2024 -> true
2026 -> false
How it works
- 1900 is divisible by 100 but not by 400, so it is not a leap year. 2000 is divisible by 400, so it is.
Read C++ Operators.
FizzBuzz in C++
Description: Print 1 to 15. For multiples of 3 print Fizz, for multiples of 5 Buzz, for both FizzBuzz.
Hint:
- Check the multiples of 15 first.
Solution
#include <iostream>
int main() {
for (int i = 1; i <= 15; i++) {
if (i % 15 == 0) std::cout << "FizzBuzz\n";
else if (i % 3 == 0) std::cout << "Fizz\n";
else if (i % 5 == 0) std::cout << "Buzz\n";
else std::cout << i << '\n';
}
}
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
How it works
- The most special case (15) must be checked first, or it would print only
Fizz.
Read C++ for Loop.
Sum of the digits of a number
Description: Write digit_sum(int n). For 9475 the answer is 25.
Hint:
n % 10is the last digit,n / 10removes it.
Solution
#include <iostream>
int digit_sum(int n) {
int sum = 0;
while (n > 0) {
sum += n % 10;
n /= 10;
}
return sum;
}
int main() {
std::cout << digit_sum(9475) << ' ' << digit_sum(100) << ' ' << digit_sum(0) << '\n';
}
25 1 0
How it works
- The loop adds the last digit and cuts it off, until the number is 0.
Read C++ while Loop.
Print a multiplication table
Description: Print 7 x 3 = 21 for 1 to 10.
Hint:
- A for loop and a format with a width, like
{:2}.
Solution
#include <print>
int main() {
int n = 7;
for (int i = 1; i <= 10; i++) {
std::println("{} x {:2} = {:2}", n, i, n * i);
}
}
7 x 1 = 7
7 x 2 = 14
7 x 3 = 21
7 x 4 = 28
7 x 5 = 35
7 x 6 = 42
7 x 7 = 49
7 x 8 = 56
7 x 9 = 63
7 x 10 = 70
How it works
{:2}uses at least 2 places, so the numbers line up.
Read C++ for Loop.
Check prime numbers and list the primes up to 30
Description: Write is_prime(int n) and print the primes from 1 to 30.
Hint:
- Test divisors while
i * i <= n.
Solution
#include <iostream>
bool is_prime(int n) {
if (n < 2) return false;
for (int i = 2; i * i <= n; i++) {
if (n % i == 0) return false;
}
return true;
}
int main() {
for (int n = 1; n <= 30; n++) {
if (is_prime(n)) std::cout << n << ' ';
}
std::cout << '\n';
}
2 3 5 7 11 13 17 19 23 29
How it works
- If
nhas a divisor bigger than its square root, it also has a smaller one, so we can stop early.
Read C++ Functions.
Reverse a string
Description: Reverse "C++ Rocks".
Hint:
std::reverseis in<algorithm>. A string can also be built fromrbegin()andrend().
Solution
#include <algorithm>
#include <iostream>
#include <string>
int main() {
std::string s = "C++ Rocks";
std::string a;
for (int i = static_cast<int>(s.size()) - 1; i >= 0; i--) a += s[i];
std::string b = s;
std::reverse(b.begin(), b.end());
std::string c(s.rbegin(), s.rend());
std::cout << a << '\n' << b << '\n' << c << '\n';
}
skcoR ++C
skcoR ++C
skcoR ++C
How it works
- The three ways give the same result. The library way is the shortest and the clearest.
Read C++ Strings.
Check if a string is a palindrome
Description: Write is_palindrome(std::string). Ignore the case and the spaces. Test “Madam”, “Nurses run” and “C++”.
Hint:
- Clean the text, then compare it with its reverse.
Solution
#include <algorithm>
#include <cctype>
#include <iostream>
#include <string>
bool is_palindrome(std::string s) {
std::erase_if(s, [](unsigned char c) { return !std::isalnum(c); });
std::transform(s.begin(), s.end(), s.begin(), [](unsigned char c) { return std::tolower(c); });
return std::equal(s.begin(), s.begin() + s.size() / 2, s.rbegin());
}
int main() {
std::cout << std::boolalpha;
for (std::string t : {"Madam", "Nurses run", "C++"}) {
std::cout << t << " -> " << is_palindrome(t) << '\n';
}
}
Madam -> true
Nurses run -> true
C++ -> true
How it works
- We remove everything which is not a letter or digit, and make the rest lower case.
std::equalcompares the first half with the reversed second half.
Read C++ Strings.
Count the vowels in a string
Description: Count the vowels and the consonants in "Learn C++ Programming".
Hint:
- Use
std::isalphaand look for the letter in"aeiou".
Solution
#include <cctype>
#include <iostream>
#include <string>
int main() {
std::string text = "Learn C++ Programming";
int vowels = 0, consonants = 0;
for (unsigned char c : text) {
if (!std::isalpha(c)) continue;
if (std::string("aeiou").find(static_cast<char>(std::tolower(c))) != std::string::npos) vowels++;
else consonants++;
}
std::cout << "Vowels: " << vowels << ", consonants: " << consonants << '\n';
}
Vowels: 5, consonants: 12
How it works
- Spaces,
+signs and other characters are skipped withcontinue.
Read C++ Strings.
Find the second largest number in a vector
Description: Find the second largest number in {12, 35, 1, 10, 34, 1} without sorting.
Hint:
- Keep
largestandsecond, and update both in one loop.
Solution
#include <climits>
#include <iostream>
#include <vector>
int second_largest(const std::vector<int>& v) {
int largest = INT_MIN, second = INT_MIN;
for (int n : v) {
if (n > largest) {
second = largest;
largest = n;
} else if (n > second && n != largest) {
second = n;
}
}
return second;
}
int main() {
std::cout << second_largest({12, 35, 1, 10, 34, 1}) << '\n';
std::cout << second_largest({5, 5, 5, 2}) << '\n';
}
34
2
How it works
- When a bigger value comes, the old biggest becomes the second one.
Read C++ Vectors.
Sort a vector with bubble sort
Description: Sort {64, 34, 25, 12, 22, 11, 90} without std::sort, then check the result with std::sort.
Hint:
- Swap neighbours which are in the wrong order. Repeat.
Solution
#include <algorithm>
#include <iostream>
#include <vector>
void bubble_sort(std::vector<int>& a) {
for (std::size_t i = 0; i + 1 < a.size(); i++) {
bool swapped = false;
for (std::size_t j = 0; j + 1 < a.size() - i; j++) {
if (a[j] > a[j + 1]) {
std::swap(a[j], a[j + 1]);
swapped = true;
}
}
if (!swapped) break;
}
}
int main() {
std::vector<int> data = {64, 34, 25, 12, 22, 11, 90};
auto check = data;
bubble_sort(data);
std::sort(check.begin(), check.end());
for (int x : data) std::cout << x << ' ';
std::cout << '\n' << (data == check) << '\n';
}
11 12 22 25 34 64 90
1
How it works
- After every round of the outer loop, the biggest remaining item is in its place.
- It is slow (O(n squared)). Real code uses
std::sort.
Read C++ Vectors.
Transpose a matrix
Description: Transpose {{1,2,3},{4,5,6}} to {{1,4},{2,5},{3,6}}.
Hint:
- The new matrix has
colsrows androwscolumns:t[j][i] = m[i][j].
Solution
#include <iostream>
#include <vector>
using Matrix = std::vector<std::vector<int>>;
Matrix transpose(const Matrix& m) {
std::size_t rows = m.size(), cols = m[0].size();
Matrix t(cols, std::vector<int>(rows));
for (std::size_t i = 0; i < rows; i++)
for (std::size_t j = 0; j < cols; j++)
t[j][i] = m[i][j];
return t;
}
int main() {
for (const auto& row : transpose({{1, 2, 3}, {4, 5, 6}})) {
for (int v : row) std::cout << v << ' ';
std::cout << '\n';
}
}
1 4
2 5
3 6
How it works
- A 2 x 3 matrix gives a 3 x 2 matrix, so the new vector has the sizes swapped.
Read C++ Vectors.
Build a BankAccount class
Description: Make a class BankAccount with a private balance. Add deposit and withdraw. Throw an exception for a negative deposit and for a withdraw bigger than the balance.
Hint:
- Use
std::invalid_argumentandstd::runtime_error.
Solution
#include <iostream>
#include <stdexcept>
class BankAccount {
public:
void deposit(double amount) {
if (amount <= 0) throw std::invalid_argument("Deposit must be positive");
balance += amount;
}
void withdraw(double amount) {
if (amount > balance) throw std::runtime_error("Not enough balance");
balance -= amount;
}
double get_balance() const { return balance; }
private:
double balance = 0;
};
int main() {
BankAccount acc;
acc.deposit(1000);
acc.withdraw(250);
std::cout << acc.get_balance() << '\n';
try {
acc.withdraw(5000);
} catch (const std::exception& e) {
std::cout << "Error: " << e.what() << '\n';
}
try {
acc.deposit(-5);
} catch (const std::exception& e) {
std::cout << "Error: " << e.what() << '\n';
}
}
750
Error: Not enough balance
Error: Deposit must be positive
How it works
- The balance is private, so only the two methods can change it, and both check the value.
Read Encapsulation.
Calculate areas with polymorphism
Description: Make an abstract class Shape with a pure virtual function area(). Write Circle (radius 2) and Rectangle (3 x 4). Put them in one container and print the total area.
Hint:
- Use
std::vector<std::unique_ptr<Shape>>and a virtual destructor.
Solution
#include <iomanip>
#include <iostream>
#include <memory>
#include <numbers>
#include <vector>
class Shape {
public:
virtual ~Shape() = default;
virtual double area() const = 0;
};
class Circle : public Shape {
public:
explicit Circle(double r) : r(r) {}
double area() const override { return std::numbers::pi * r * r; }
private:
double r;
};
class Rectangle : public Shape {
public:
Rectangle(double w, double h) : w(w), h(h) {}
double area() const override { return w * h; }
private:
double w, h;
};
int main() {
std::vector<std::unique_ptr<Shape>> shapes;
shapes.push_back(std::make_unique<Circle>(2));
shapes.push_back(std::make_unique<Rectangle>(3, 4));
double total = 0;
for (const auto& s : shapes) total += s->area();
std::cout << std::fixed << std::setprecision(2) << "Total area: " << total << '\n';
}
Total area: 24.57
How it works
- The loop uses the base type. C++ calls the
area()of the real object (virtual function). - The virtual destructor makes sure that the right destructor runs when the smart pointers delete the objects.
Read Polymorphism and Abstract Classes.
Overload operators for a Money class
Description: Write a class Money which keeps rupees and paise. Overload +, == and <<. Add Rs. 10.75 and Rs. 5.50, and print Rs. 16.25.
Hint:
- Keep the value in paise (a whole number) to avoid decimal errors.
Solution
#include <iostream>
class Money {
public:
explicit Money(long long paise) : paise(paise) {}
Money operator+(const Money& o) const { return Money(paise + o.paise); }
bool operator==(const Money&) const = default;
friend std::ostream& operator<<(std::ostream& os, const Money& m) {
return os << "Rs. " << m.paise / 100 << '.' << (m.paise % 100 < 10 ? "0" : "") << m.paise % 100;
}
private:
long long paise;
};
int main() {
Money a(1075), b(550);
std::cout << a + b << '\n';
std::cout << std::boolalpha << (a + b == Money(1625)) << '\n';
}
Rs. 16.25
true
How it works
- Money is kept as a whole number of paise, so there is no decimal rounding problem.
operator<<is a friend function, because the stream is on the left side.
Read Operator Overloading.
Write a generic maximum template
Description: Write a function template max_of which returns the bigger of two values. Use it with int, double and std::string. Then limit it to types which can be compared with a concept.
Hint:
std::totally_orderedis a ready concept for comparable types.
Solution
#include <concepts>
#include <iostream>
#include <string>
template <std::totally_ordered T>
T max_of(T a, T b) {
return a > b ? a : b;
}
int main() {
std::cout << max_of(3, 9) << '\n';
std::cout << max_of(2.5, 1.5) << '\n';
std::cout << max_of(std::string("pear"), std::string("apple")) << '\n';
}
9
2.5
pear
How it works
- The compiler makes one version of the function for each type you use.
- The concept gives a clear error when the type can not be compared.
Read C++ Templates.
Count the frequency of words with a map
Description: Count the words of "the cat and the dog and the bird", and print them in alphabetical order.
Hint:
std::istringstreamreads word by word.std::mapkeeps sorted keys.
Solution
#include <iostream>
#include <map>
#include <sstream>
#include <string>
int main() {
std::istringstream in("the cat and the dog and the bird");
std::map<std::string, int> count;
std::string word;
while (in >> word) {
count[word]++;
}
for (const auto& [w, n] : count) {
std::cout << w << " = " << n << '\n';
}
}
and = 2
bird = 1
cat = 1
dog = 1
the = 3
How it works
count[word]++creates the key with 0 when it is new, and then adds 1.
Read STL Containers.