cpp
Parameters
02_Parameters⚙️cpp
/**
* ============================================================
* C++ FUNCTION PARAMETERS
* ============================================================
*
* This file covers:
* - Pass by value
* - Pass by reference
* - Pass by pointer
* - Const parameters
* - Array parameters
* - Default arguments
*
* Compile: g++ -std=c++17 -Wall 01_parameters.cpp -o parameters
* Run: ./parameters
*
* ============================================================
*/
#include <iostream>
#include <vector>
#include <string>
using namespace std;
// ============================================================
// FUNCTION DECLARATIONS
// ============================================================
// Pass by value
void incrementByValue(int x);
// Pass by reference
void incrementByReference(int& x);
void swap(int& a, int& b);
// Pass by pointer
void incrementByPointer(int* x);
void setToZero(int* ptr);
// Const parameters
void printValue(const int& x);
void printString(const string& str);
int sumArray(const int arr[], int size);
void displayVector(const vector<int>& vec);
// Array parameters
void fillArray(int arr[], int size, int value);
void printArray(int arr[], int size);
void modifyArray(int* arr, int size);
// Default arguments
void greet(string name = "Guest");
void printRectangle(int width, int height, char ch = '*');
int power(int base, int exp = 2);
// ============================================================
// MAIN FUNCTION
// ============================================================
int main() {
cout << "============================================" << endl;
cout << " C++ FUNCTION PARAMETERS" << endl;
cout << "============================================" << endl << endl;
// ========================================================
// PART 1: PASS BY VALUE
// ========================================================
cout << "--- PART 1: PASS BY VALUE ---" << endl << endl;
/*
* Pass by value: A COPY of the argument is passed
* - Original variable is NOT modified
* - Safe, but copies large objects
*/
int num = 10;
cout << "Before incrementByValue: num = " << num << endl;
incrementByValue(num);
cout << "After incrementByValue: num = " << num << " (unchanged!)" << endl;
// Pass by value creates a copy
// Good for: small types (int, char, etc.), when you don't want to modify original
cout << endl;
// ========================================================
// PART 2: PASS BY REFERENCE
// ========================================================
cout << "--- PART 2: PASS BY REFERENCE ---" << endl << endl;
/*
* Pass by reference: The actual variable is passed (via alias)
* - Original variable CAN be modified
* - No copying - efficient for large objects
* - Syntax: use & after the type
*/
int value = 10;
cout << "Before incrementByReference: value = " << value << endl;
incrementByReference(value);
cout << "After incrementByReference: value = " << value << " (modified!)" << endl;
// Swap example
int a = 5, b = 10;
cout << "\nBefore swap: a=" << a << ", b=" << b << endl;
swap(a, b);
cout << "After swap: a=" << a << ", b=" << b << endl;
cout << endl;
// ========================================================
// PART 3: PASS BY POINTER
// ========================================================
cout << "--- PART 3: PASS BY POINTER ---" << endl << endl;
/*
* Pass by pointer: Address of variable is passed
* - Original variable CAN be modified (via dereference)
* - Can be nullptr (handle null checks!)
* - Syntax: use * after the type, pass &variable
*/
int x = 10;
cout << "Before incrementByPointer: x = " << x << endl;
incrementByPointer(&x); // Pass address using &
cout << "After incrementByPointer: x = " << x << " (modified!)" << endl;
// Pointer can be null
int y = 100;
setToZero(&y);
cout << "After setToZero: y = " << y << endl;
setToZero(nullptr); // Safe - function checks for null
cout << endl;
// ========================================================
// PART 4: CONST PARAMETERS
// ========================================================
cout << "--- PART 4: CONST PARAMETERS ---" << endl << endl;
/*
* Const reference: Pass by reference but prevent modification
* - Efficient (no copy)
* - Safe (can't modify)
* - Best of both worlds!
*/
int number = 42;
printValue(number); // Can pass variable
printValue(100); // Can pass literal (const ref allows this!)
string longString = "This is a very long string that we don't want to copy";
printString(longString);
// Const with arrays
int arr[] = {1, 2, 3, 4, 5};
int sum = sumArray(arr, 5);
cout << "Sum of array: " << sum << endl;
// Const with vectors
vector<int> vec = {10, 20, 30, 40, 50};
displayVector(vec);
cout << endl;
// ========================================================
// PART 5: ARRAY PARAMETERS
// ========================================================
cout << "--- PART 5: ARRAY PARAMETERS ---" << endl << endl;
/*
* Arrays decay to pointers when passed to functions
* - int arr[] is same as int* arr
* - Size must be passed separately
* - Original array CAN be modified
*/
int myArray[5];
fillArray(myArray, 5, 42);
cout << "After fillArray: ";
printArray(myArray, 5);
modifyArray(myArray, 5);
cout << "After modifyArray: ";
printArray(myArray, 5);
cout << endl;
// ========================================================
// PART 6: DEFAULT ARGUMENTS
// ========================================================
cout << "--- PART 6: DEFAULT ARGUMENTS ---" << endl << endl;
/*
* Default arguments: Values used when argument is not provided
* - Declared in function declaration (not definition)
* - Must be at the END of parameter list
* - Once you have a default, all following must have defaults
*/
greet(); // Uses default "Guest"
greet("Alice"); // Uses provided argument
cout << endl;
printRectangle(5, 3); // Uses default '*'
cout << endl;
printRectangle(5, 3, '#'); // Uses provided '#'
cout << endl;
cout << "power(3): " << power(3) << " (uses default exp=2)" << endl;
cout << "power(2, 8): " << power(2, 8) << " (explicit exp=8)" << endl;
cout << endl;
// ========================================================
// PART 7: COMPARISON SUMMARY
// ========================================================
cout << "--- PART 7: COMPARISON ---" << endl << endl;
cout << "┌──────────────────┬─────────────┬─────────────┬─────────────┐" << endl;
cout << "│ Feature │ By Value │ By Reference│ By Pointer │" << endl;
cout << "├──────────────────┼─────────────┼─────────────┼─────────────┤" << endl;
cout << "│ Modifies orig │ No │ Yes │ Yes │" << endl;
cout << "│ Copies data │ Yes │ No │ No │" << endl;
cout << "│ Can be null │ N/A │ No │ Yes │" << endl;
cout << "│ Syntax (call) │ func(x) │ func(x) │ func(&x) │" << endl;
cout << "│ Syntax (param) │ int x │ int& x │ int* x │" << endl;
cout << "└──────────────────┴─────────────┴─────────────┴─────────────┘" << endl;
cout << "\n💡 Best Practices:" << endl;
cout << "• Small types (int, char): pass by value" << endl;
cout << "• Large objects (read-only): pass by const reference" << endl;
cout << "• Need to modify: pass by reference" << endl;
cout << "• Optional/nullable: pass by pointer" << endl;
cout << endl;
cout << "============================================" << endl;
cout << "PARAMETER PASSING SUMMARY:" << endl;
cout << "============================================" << endl;
cout << "• By value: copies, original unchanged" << endl;
cout << "• By reference: no copy, can modify" << endl;
cout << "• By pointer: uses address, can be null" << endl;
cout << "• Use const& for read-only efficiency" << endl;
cout << "• Default args must be at end" << endl;
cout << "============================================" << endl;
return 0;
}
// ============================================================
// FUNCTION DEFINITIONS
// ============================================================
// Pass by value - receives a COPY
void incrementByValue(int x) {
x++; // Only modifies the local copy
cout << " Inside function: x = " << x << endl;
}
// Pass by reference - receives the ACTUAL variable
void incrementByReference(int& x) {
x++; // Modifies the original variable
}
// Swap using references
void swap(int& a, int& b) {
int temp = a;
a = b;
b = temp;
}
// Pass by pointer
void incrementByPointer(int* x) {
if (x != nullptr) { // Always check for null!
(*x)++; // Dereference and increment
}
}
void setToZero(int* ptr) {
if (ptr != nullptr) {
*ptr = 0;
} else {
cout << "Received null pointer - no action taken" << endl;
}
}
// Const reference - efficient and safe
void printValue(const int& x) {
cout << "Value: " << x << endl;
// x = 10; // ERROR: cannot modify const reference
}
void printString(const string& str) {
cout << "String: " << str << endl;
// str = "changed"; // ERROR: cannot modify const reference
}
// Const with array
int sumArray(const int arr[], int size) {
int sum = 0;
for (int i = 0; i < size; i++) {
sum += arr[i];
// arr[i] = 0; // ERROR: cannot modify const array
}
return sum;
}
// Const with vector
void displayVector(const vector<int>& vec) {
cout << "Vector: ";
for (int val : vec) {
cout << val << " ";
}
cout << endl;
}
// Array parameters (arrays decay to pointers)
void fillArray(int arr[], int size, int value) {
for (int i = 0; i < size; i++) {
arr[i] = value;
}
}
void printArray(int arr[], int size) {
for (int i = 0; i < size; i++) {
cout << arr[i] << " ";
}
cout << endl;
}
// Using pointer syntax explicitly
void modifyArray(int* arr, int size) {
for (int i = 0; i < size; i++) {
arr[i] *= 2; // Double each element
}
}
// Default arguments
void greet(string name) { // Default value in declaration only!
cout << "Hello, " << name << "!" << endl;
}
void printRectangle(int width, int height, char ch) {
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
cout << ch;
}
cout << endl;
}
}
int power(int base, int exp) {
int result = 1;
for (int i = 0; i < exp; i++) {
result *= base;
}
return result;
}
// ============================================================
// EXERCISES:
// ============================================================
/*
* 1. Write a function that finds min and max of an array
* using reference parameters for the results
*
* 2. Write a function that reverses a string in place
* using pass by reference
*
* 3. Write a function with default arguments that calculates
* simple interest (principal, rate, time)
*
* 4. Write a function that safely divides two numbers
* using pointers to return both quotient and remainder
*
* 5. Write a function that modifies a vector to remove
* all negative numbers
*/