cpp
exercises
exercises.cpp⚙️cpp
/**
* References in C++ - Exercises
*
* Practice problems for understanding references.
* Each exercise includes TODO sections to complete.
*
* Compile: g++ -std=c++17 -Wall -Wextra exercises.cpp -o exercises
* Run: ./exercises
*/
#include <iostream>
#include <string>
#include <vector>
using namespace std;
// ============================================================
// Exercise 1: Basic Reference ⭐
// ============================================================
/**
* Create a reference and modify through it.
*/
void exercise1() {
int x = 100;
// TODO: Create a reference 'ref' to x
// int& ref = ...;
// TODO: Modify x through the reference to 200
cout << "x = " << x << " (expected: 200)" << endl;
}
// ============================================================
// Exercise 2: Reference vs Variable ⭐
// ============================================================
/**
* Demonstrate that reference and variable share the same address.
*/
void exercise2() {
double value = 3.14159;
double& ref = value;
// TODO: Compare addresses and print result
bool sameAddress = false; // Fix: compare &value and &ref
cout << "Same address: " << boolalpha << sameAddress << " (expected: true)" << endl;
}
// ============================================================
// Exercise 3: Swap Using References ⭐⭐
// ============================================================
/**
* Implement swap using references.
*/
void swapRef(int& a, int& b) {
// TODO: Swap the values of a and b
}
void exercise3() {
int x = 10, y = 20;
cout << "Before: x = " << x << ", y = " << y << endl;
swapRef(x, y);
cout << "After: x = " << x << ", y = " << y << " (expected: 20, 10)" << endl;
}
// ============================================================
// Exercise 4: Increment Function ⭐⭐
// ============================================================
/**
* Write a function that increments a value by a given amount.
*/
void incrementBy(int& value, int amount) {
// TODO: Increase value by amount
}
void exercise4() {
int num = 10;
incrementBy(num, 5);
cout << "After incrementBy(num, 5): " << num << " (expected: 15)" << endl;
incrementBy(num, 10);
cout << "After incrementBy(num, 10): " << num << " (expected: 25)" << endl;
}
// ============================================================
// Exercise 5: Find and Modify ⭐⭐
// ============================================================
/**
* Return reference to an element for modification.
*/
int& findElement(vector<int>& vec, int target) {
// TODO: Return reference to the element equal to target
// Assume target exists in vec
static int dummy = 0; // Remove this
return dummy; // Fix this
}
void exercise5() {
vector<int> nums = {10, 20, 30, 40, 50};
cout << "Before: ";
for (int n : nums) cout << n << " ";
cout << endl;
// Modify through returned reference
findElement(nums, 30) = 999;
cout << "After modifying 30 to 999: ";
for (int n : nums) cout << n << " ";
cout << endl;
cout << "(expected: 10 20 999 40 50)" << endl;
}
// ============================================================
// Exercise 6: Double Vector Elements ⭐⭐
// ============================================================
/**
* Use reference in range-based for to double all elements.
*/
void doubleAll(vector<int>& vec) {
// TODO: Use range-based for with reference to double each element
}
void exercise6() {
vector<int> nums = {1, 2, 3, 4, 5};
cout << "Before: ";
for (int n : nums) cout << n << " ";
cout << endl;
doubleAll(nums);
cout << "After: ";
for (int n : nums) cout << n << " ";
cout << endl;
cout << "(expected: 2 4 6 8 10)" << endl;
}
// ============================================================
// Exercise 7: const Reference Parameter ⭐⭐
// ============================================================
/**
* Calculate sum using const reference to avoid copying.
*/
int calculateSum(const vector<int>& vec) {
// TODO: Calculate and return the sum of all elements
// Use const reference in for loop for efficiency
return 0;
}
void exercise7() {
vector<int> nums = {10, 20, 30, 40, 50};
int sum = calculateSum(nums);
cout << "Sum: " << sum << " (expected: 150)" << endl;
}
// ============================================================
// Exercise 8: Find Minimum Reference ⭐⭐
// ============================================================
/**
* Return reference to the minimum element.
*/
int& findMin(vector<int>& vec) {
// TODO: Return reference to minimum element
// Assume vec is not empty
return vec[0]; // Fix this
}
void exercise8() {
vector<int> nums = {30, 10, 50, 20, 40};
cout << "Original: ";
for (int n : nums) cout << n << " ";
cout << endl;
int& minRef = findMin(nums);
cout << "Minimum: " << minRef << " (expected: 10)" << endl;
// Modify minimum through reference
minRef = 0;
cout << "After setting min to 0: ";
for (int n : nums) cout << n << " ";
cout << endl;
cout << "(expected: 30 0 50 20 40)" << endl;
}
// ============================================================
// Exercise 9: Modify String ⭐⭐
// ============================================================
/**
* Modify a string to uppercase through reference.
*/
void toUpperCase(string& str) {
// TODO: Convert each character to uppercase
// Hint: Use toupper() function
}
void exercise9() {
string text = "Hello, World!";
cout << "Before: " << text << endl;
toUpperCase(text);
cout << "After: " << text << " (expected: HELLO, WORLD!)" << endl;
}
// ============================================================
// Exercise 10: Return Multiple Values ⭐⭐⭐
// ============================================================
/**
* Find min and max using reference parameters.
*/
void findMinMax(const vector<int>& vec, int& minVal, int& maxVal) {
// TODO: Set minVal and maxVal to minimum and maximum of vec
// Assume vec is not empty
}
void exercise10() {
vector<int> nums = {23, 5, 67, 12, 89, 34};
int min = 0, max = 0;
findMinMax(nums, min, max);
cout << "Min: " << min << " (expected: 5)" << endl;
cout << "Max: " << max << " (expected: 89)" << endl;
}
// ============================================================
// Exercise 11: Append and Return ⭐⭐⭐
// ============================================================
/**
* Append to vector and return reference to last element.
*/
int& appendAndGet(vector<int>& vec, int value) {
// TODO: Append value to vec and return reference to the new element
static int dummy = 0;
return dummy; // Fix this
}
void exercise11() {
vector<int> nums = {1, 2, 3};
int& ref = appendAndGet(nums, 100);
cout << "Appended value: " << ref << endl;
ref = 999; // Modify through reference
cout << "Vector: ";
for (int n : nums) cout << n << " ";
cout << endl;
cout << "(expected: 1 2 3 999)" << endl;
}
// ============================================================
// Exercise 12: Reference in Class ⭐⭐⭐
// ============================================================
/**
* Create a class that provides reference access to its data.
*/
class Container {
private:
int data[5];
public:
Container() {
for (int i = 0; i < 5; i++) {
data[i] = (i + 1) * 10; // 10, 20, 30, 40, 50
}
}
// TODO: Implement at() that returns reference to element at index
int& at(int index) {
static int dummy = 0;
return dummy; // Fix this
}
void print() const {
cout << "Container: ";
for (int i = 0; i < 5; i++) {
cout << data[i] << " ";
}
cout << endl;
}
};
void exercise12() {
Container c;
c.print();
c.at(2) = 999;
cout << "After c.at(2) = 999: ";
c.print();
cout << "(expected: 10 20 999 40 50)" << endl;
}
// ============================================================
// Exercise 13: Count Occurrences (const ref) ⭐⭐⭐
// ============================================================
/**
* Count occurrences using const reference for efficiency.
*/
int countOccurrences(const vector<string>& vec, const string& target) {
// TODO: Count how many times target appears in vec
// Use const reference in loop
return 0;
}
void exercise13() {
vector<string> words = {"apple", "banana", "apple", "cherry", "apple"};
int count = countOccurrences(words, "apple");
cout << "Count of 'apple': " << count << " (expected: 3)" << endl;
count = countOccurrences(words, "grape");
cout << "Count of 'grape': " << count << " (expected: 0)" << endl;
}
// ============================================================
// Exercise 14: Transform with Function Reference ⭐⭐⭐
// ============================================================
/**
* Apply a transformation function to each element.
*/
void transform(vector<int>& vec, int (*func)(int)) {
// TODO: Apply func to each element using reference
}
int square(int x) { return x * x; }
// ⚠️ LEARNING NOTE: Originally named 'negate' but that conflicts with std::negate!
// When you use 'using namespace std', all std:: names become visible.
// std::negate is a function object in <functional>, causing ambiguity.
// FIX: Rename to avoid conflict with standard library names
int myNegate(int x) { return -x; }
void exercise14() {
vector<int> nums = {1, 2, 3, 4, 5};
cout << "Original: ";
for (int n : nums) cout << n << " ";
cout << endl;
transform(nums, square);
cout << "After square: ";
for (int n : nums) cout << n << " ";
cout << endl;
cout << "(expected: 1 4 9 16 25)" << endl;
transform(nums, myNegate); // Use renamed function
cout << "After negate: ";
for (int n : nums) cout << n << " ";
cout << endl;
cout << "(expected: -1 -4 -9 -16 -25)" << endl;
}
// ============================================================
// Exercise 15: Linked Modification ⭐⭐⭐
// ============================================================
/**
* Modify values through a chain of references.
*/
void exercise15() {
int original = 100;
// TODO: Create ref1 as reference to original
// TODO: Create ref2 as reference to ref1 (which is also to original)
// TODO: Create ref3 as reference to ref2 (which is also to original)
// TODO: Modify original through ref3 to 999
// Uncomment and fix:
// int& ref1 = ...;
// int& ref2 = ...;
// int& ref3 = ...;
// ref3 = 999;
cout << "original = " << original << " (expected: 999)" << endl;
}
// ============================================================
// TEST RUNNER
// ============================================================
int main() {
cout << "╔════════════════════════════════════════════════════════════╗" << endl;
cout << "║ REFERENCES - EXERCISES ║" << endl;
cout << "╚════════════════════════════════════════════════════════════╝" << endl;
cout << "\n=== Exercise 1: Basic Reference ===" << endl;
exercise1();
cout << "\n=== Exercise 2: Reference vs Variable ===" << endl;
exercise2();
cout << "\n=== Exercise 3: Swap Using References ===" << endl;
exercise3();
cout << "\n=== Exercise 4: Increment Function ===" << endl;
exercise4();
cout << "\n=== Exercise 5: Find and Modify ===" << endl;
exercise5();
cout << "\n=== Exercise 6: Double Vector Elements ===" << endl;
exercise6();
cout << "\n=== Exercise 7: const Reference Parameter ===" << endl;
exercise7();
cout << "\n=== Exercise 8: Find Minimum Reference ===" << endl;
exercise8();
cout << "\n=== Exercise 9: Modify String ===" << endl;
exercise9();
cout << "\n=== Exercise 10: Return Multiple Values ===" << endl;
exercise10();
cout << "\n=== Exercise 11: Append and Return ===" << endl;
exercise11();
cout << "\n=== Exercise 12: Reference in Class ===" << endl;
exercise12();
cout << "\n=== Exercise 13: Count Occurrences ===" << endl;
exercise13();
cout << "\n=== Exercise 14: Transform with Function ===" << endl;
exercise14();
cout << "\n=== Exercise 15: Linked Modification ===" << endl;
exercise15();
cout << "\n╔════════════════════════════════════════════════════════════╗" << endl;
cout << "║ Complete the TODO sections and re-run! ║" << endl;
cout << "╚════════════════════════════════════════════════════════════╝" << endl;
return 0;
}
// ============================================================
// ANSWER KEY
// ============================================================
/*
// Exercise 1
int& ref = x;
ref = 200;
// Exercise 2
bool sameAddress = (&value == &ref);
// Exercise 3
void swapRef(int& a, int& b) {
int temp = a;
a = b;
b = temp;
}
// Exercise 4
void incrementBy(int& value, int amount) {
value += amount;
}
// Exercise 5
int& findElement(vector<int>& vec, int target) {
for (int& elem : vec) {
if (elem == target) {
return elem;
}
}
return vec[0]; // Fallback
}
// Exercise 6
void doubleAll(vector<int>& vec) {
for (int& n : vec) {
n *= 2;
}
}
// Exercise 7
int calculateSum(const vector<int>& vec) {
int sum = 0;
for (const int& n : vec) {
sum += n;
}
return sum;
}
// Exercise 8
int& findMin(vector<int>& vec) {
int minIdx = 0;
for (size_t i = 1; i < vec.size(); i++) {
if (vec[i] < vec[minIdx]) {
minIdx = i;
}
}
return vec[minIdx];
}
// Exercise 9
void toUpperCase(string& str) {
for (char& c : str) {
c = toupper(c);
}
}
// Exercise 10
void findMinMax(const vector<int>& vec, int& minVal, int& maxVal) {
minVal = maxVal = vec[0];
for (const int& n : vec) {
if (n < minVal) minVal = n;
if (n > maxVal) maxVal = n;
}
}
// Exercise 11
int& appendAndGet(vector<int>& vec, int value) {
vec.push_back(value);
return vec.back();
}
// Exercise 12
int& at(int index) {
return data[index];
}
// Exercise 13
int countOccurrences(const vector<string>& vec, const string& target) {
int count = 0;
for (const string& s : vec) {
if (s == target) count++;
}
return count;
}
// Exercise 14
void transform(vector<int>& vec, int (*func)(int)) {
for (int& n : vec) {
n = func(n);
}
}
// Exercise 15
int& ref1 = original;
int& ref2 = ref1;
int& ref3 = ref2;
ref3 = 999;
*/