cpp
examples
examples.cpp⚙️cpp
/**
* Function Parameters in C++ - Comprehensive Examples
*
* Demonstrates:
* - Pass by value, reference, and pointer
* - Const correctness
* - Default arguments
* - Array parameters
* - Multiple return values via out parameters
*
* Compile: g++ -std=c++17 -Wall -Wextra examples.cpp -o examples
* Run: ./examples
*/
#include <iostream>
#include <string>
#include <vector>
#include <cmath>
using namespace std;
// ============================================================
// SECTION 1: PASS BY VALUE
// ============================================================
/**
* Pass by value - receives a copy.
* Original value is NOT modified.
*/
void incrementByValue(int x) {
x++; // Only modifies local copy
cout << " Inside function: x = " << x << endl;
}
/**
* Pass by value with string (expensive copy!)
*/
void printUpperByValue(string s) {
for (char& c : s) {
c = toupper(c);
}
cout << " Inside: " << s << endl;
}
/**
* When pass-by-value is appropriate
*/
int square(int n) {
return n * n; // Small type, no need for reference
}
double circleArea(double radius) {
return 3.14159 * radius * radius;
}
// ============================================================
// SECTION 2: PASS BY REFERENCE
// ============================================================
/**
* Pass by reference - modifies original.
*/
void incrementByRef(int& x) {
x++; // Modifies caller's variable
}
/**
* Classic swap using references
*/
void swap(int& a, int& b) {
int temp = a;
a = b;
b = temp;
}
/**
* Swap any type using templates
*/
template<typename T>
void swapGeneric(T& a, T& b) {
T temp = a;
a = b;
b = temp;
}
/**
* Modify string in place
*/
void toUppercase(string& s) {
for (char& c : s) {
c = toupper(c);
}
}
/**
* Clear and fill a vector
*/
void fillWithRange(vector<int>& v, int start, int end) {
v.clear();
for (int i = start; i <= end; i++) {
v.push_back(i);
}
}
// ============================================================
// SECTION 3: CONST REFERENCE (Read-Only, Efficient)
// ============================================================
/**
* Const reference - read-only access, no copy
*/
void printVector(const vector<int>& v) {
cout << " [";
for (size_t i = 0; i < v.size(); i++) {
cout << v[i];
if (i < v.size() - 1) cout << ", ";
}
cout << "]" << endl;
}
/**
* Calculate sum without modifying or copying
*/
long long sum(const vector<int>& numbers) {
long long total = 0;
for (int n : numbers) {
total += n;
}
return total;
}
/**
* Find maximum in vector
*/
int findMax(const vector<int>& v) {
if (v.empty()) return 0;
int maxVal = v[0];
for (int n : v) {
if (n > maxVal) maxVal = n;
}
return maxVal;
}
/**
* String analysis - const ref for efficiency
*/
int countVowels(const string& s) {
int count = 0;
for (char c : s) {
c = tolower(c);
if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') {
count++;
}
}
return count;
}
// ============================================================
// SECTION 4: PASS BY POINTER
// ============================================================
/**
* Pointer parameter - can be nullptr
*/
void incrementByPtr(int* ptr) {
if (ptr != nullptr) {
(*ptr)++;
}
}
/**
* Optional output parameter
*/
bool safeDivide(int a, int b, double* result) {
if (b == 0) {
return false;
}
if (result != nullptr) {
*result = static_cast<double>(a) / b;
}
return true;
}
/**
* Multiple outputs via pointers
*/
void getMinMax(const vector<int>& v, int* outMin, int* outMax) {
if (v.empty()) return;
int minVal = v[0], maxVal = v[0];
for (int n : v) {
if (n < minVal) minVal = n;
if (n > maxVal) maxVal = n;
}
if (outMin) *outMin = minVal;
if (outMax) *outMax = maxVal;
}
/**
* Search with optional index output
*/
bool findElement(const vector<int>& v, int target, int* outIndex) {
for (size_t i = 0; i < v.size(); i++) {
if (v[i] == target) {
if (outIndex) *outIndex = static_cast<int>(i);
return true;
}
}
return false;
}
// ============================================================
// SECTION 5: CONST POINTER VARIATIONS
// ============================================================
/**
* Pointer to const - can't modify data through pointer
*/
void printArray(const int* arr, int size) {
for (int i = 0; i < size; i++) {
cout << arr[i] << " ";
}
cout << endl;
}
/**
* Const pointer - can't reassign the pointer itself
*/
void fillArray(int* const arr, int size, int value) {
// arr = nullptr; // ERROR: can't reassign const pointer
for (int i = 0; i < size; i++) {
arr[i] = value; // OK: can modify data
}
}
// ============================================================
// SECTION 6: DEFAULT ARGUMENTS
// ============================================================
/**
* Simple default argument
*/
void greet(const string& name, const string& greeting = "Hello") {
cout << greeting << ", " << name << "!" << endl;
}
/**
* Multiple defaults
*/
void printMessage(const string& msg,
int times = 1,
const string& prefix = ">> ",
const string& suffix = "") {
for (int i = 0; i < times; i++) {
cout << prefix << msg << suffix << endl;
}
}
/**
* Power function with default exponent
*/
double power(double base, int exp = 2) {
double result = 1.0;
bool negative = exp < 0;
exp = abs(exp);
for (int i = 0; i < exp; i++) {
result *= base;
}
return negative ? 1.0 / result : result;
}
/**
* Format number with optional precision and prefix
*/
string formatNumber(double value, int precision = 2, const string& prefix = "") {
string result = prefix;
// Simple formatting (not production-quality)
int wholePart = static_cast<int>(value);
double fracPart = value - wholePart;
result += to_string(wholePart) + ".";
for (int i = 0; i < precision; i++) {
fracPart *= 10;
result += to_string(static_cast<int>(fracPart) % 10);
}
return result;
}
// ============================================================
// SECTION 7: ARRAY PARAMETERS
// ============================================================
/**
* Array decays to pointer - size is NOT preserved
*/
void processArray(int arr[], int size) {
// sizeof(arr) would give pointer size, not array size!
for (int i = 0; i < size; i++) {
arr[i] *= 2;
}
}
/**
* Safer: explicitly use pointer
*/
int arraySum(const int* arr, size_t size) {
int total = 0;
for (size_t i = 0; i < size; i++) {
total += arr[i];
}
return total;
}
/**
* Template: preserve array size
*/
template<size_t N>
void printFixedArray(const int (&arr)[N]) {
cout << " Array of size " << N << ": ";
for (size_t i = 0; i < N; i++) {
cout << arr[i] << " ";
}
cout << endl;
}
// ============================================================
// SECTION 8: MIXED PARAMETER TYPES
// ============================================================
/**
* Complex function with multiple parameter types
*/
bool processData(const vector<int>& input, // Read-only input
vector<int>& output, // Output container
int* errorCount = nullptr, // Optional error count
int threshold = 0) { // Default threshold
output.clear();
int errors = 0;
for (int val : input) {
if (val >= threshold) {
output.push_back(val);
} else {
errors++;
}
}
if (errorCount) *errorCount = errors;
return errors == 0;
}
/**
* Configuration via struct (alternative to many parameters)
*/
struct PrintConfig {
string prefix = "";
string suffix = "";
string separator = ", ";
bool showIndices = false;
};
void printVectorConfigured(const vector<int>& v, const PrintConfig& config = {}) {
cout << config.prefix;
for (size_t i = 0; i < v.size(); i++) {
if (config.showIndices) {
cout << "[" << i << "]=";
}
cout << v[i];
if (i < v.size() - 1) cout << config.separator;
}
cout << config.suffix << endl;
}
// ============================================================
// DEMONSTRATION FUNCTIONS
// ============================================================
void demonstratePassByValue() {
cout << "\n╔══════════════════════════════════════════════════════════════╗" << endl;
cout << "║ SECTION 1: Pass By Value ║" << endl;
cout << "╚══════════════════════════════════════════════════════════════╝" << endl;
int x = 10;
cout << "Before incrementByValue: x = " << x << endl;
incrementByValue(x);
cout << "After incrementByValue: x = " << x << " (unchanged!)" << endl;
cout << "\nSquare: " << square(5) << endl;
cout << "Circle area (r=3): " << circleArea(3) << endl;
string s = "hello";
cout << "\nBefore printUpperByValue: s = " << s << endl;
printUpperByValue(s);
cout << "After printUpperByValue: s = " << s << " (unchanged!)" << endl;
}
void demonstratePassByReference() {
cout << "\n╔══════════════════════════════════════════════════════════════╗" << endl;
cout << "║ SECTION 2: Pass By Reference ║" << endl;
cout << "╚══════════════════════════════════════════════════════════════╝" << endl;
int x = 10;
cout << "Before incrementByRef: x = " << x << endl;
incrementByRef(x);
cout << "After incrementByRef: x = " << x << " (modified!)" << endl;
int a = 5, b = 10;
cout << "\nBefore swap: a = " << a << ", b = " << b << endl;
swap(a, b);
cout << "After swap: a = " << a << ", b = " << b << endl;
string s = "hello world";
cout << "\nBefore toUppercase: s = " << s << endl;
toUppercase(s);
cout << "After toUppercase: s = " << s << endl;
vector<int> v;
fillWithRange(v, 1, 5);
cout << "\nAfter fillWithRange(1, 5): ";
printVector(v);
}
void demonstrateConstReference() {
cout << "\n╔══════════════════════════════════════════════════════════════╗" << endl;
cout << "║ SECTION 3: Const Reference (Efficient) ║" << endl;
cout << "╚══════════════════════════════════════════════════════════════╝" << endl;
vector<int> numbers = {3, 1, 4, 1, 5, 9, 2, 6};
cout << "Vector: ";
printVector(numbers);
cout << "Sum: " << sum(numbers) << endl;
cout << "Max: " << findMax(numbers) << endl;
string text = "Hello World";
cout << "\nVowels in \"" << text << "\": " << countVowels(text) << endl;
}
void demonstratePassByPointer() {
cout << "\n╔══════════════════════════════════════════════════════════════╗" << endl;
cout << "║ SECTION 4: Pass By Pointer ║" << endl;
cout << "╚══════════════════════════════════════════════════════════════╝" << endl;
int x = 10;
cout << "Before incrementByPtr: x = " << x << endl;
incrementByPtr(&x);
cout << "After incrementByPtr: x = " << x << endl;
incrementByPtr(nullptr); // Safe: checks for null
cout << "incrementByPtr(nullptr): No crash!" << endl;
double result;
cout << "\nsafeDivide(10, 3): ";
if (safeDivide(10, 3, &result)) {
cout << result << endl;
}
cout << "safeDivide(10, 0): ";
if (!safeDivide(10, 0, &result)) {
cout << "Division by zero!" << endl;
}
// Just checking without needing result
cout << "safeDivide(10, 2, nullptr): "
<< (safeDivide(10, 2, nullptr) ? "OK" : "Failed") << endl;
vector<int> v = {5, 2, 8, 1, 9, 3};
int minVal, maxVal;
getMinMax(v, &minVal, &maxVal);
cout << "\nMin: " << minVal << ", Max: " << maxVal << endl;
// Only get max
getMinMax(v, nullptr, &maxVal);
cout << "Max only: " << maxVal << endl;
int idx;
if (findElement(v, 8, &idx)) {
cout << "Found 8 at index " << idx << endl;
}
}
void demonstrateDefaultArguments() {
cout << "\n╔══════════════════════════════════════════════════════════════╗" << endl;
cout << "║ SECTION 5: Default Arguments ║" << endl;
cout << "╚══════════════════════════════════════════════════════════════╝" << endl;
greet("Alice"); // Uses default greeting
greet("Bob", "Welcome"); // Custom greeting
cout << "\nprintMessage with various defaults:" << endl;
printMessage("Test"); // All defaults
printMessage("Test", 2); // Custom times
printMessage("Test", 3, "## "); // Custom prefix
printMessage("Test", 1, "-> ", " <-"); // All custom
cout << "\nPower function:" << endl;
cout << "power(5) = " << power(5) << " (default: square)" << endl;
cout << "power(2, 10) = " << power(2, 10) << endl;
cout << "power(2, -3) = " << power(2, -3) << endl;
cout << "\nNumber formatting:" << endl;
cout << formatNumber(3.14159) << endl;
cout << formatNumber(3.14159, 4) << endl;
cout << formatNumber(99.5, 2, "$") << endl;
}
void demonstrateArrayParameters() {
cout << "\n╔══════════════════════════════════════════════════════════════╗" << endl;
cout << "║ SECTION 6: Array Parameters ║" << endl;
cout << "╚══════════════════════════════════════════════════════════════╝" << endl;
int arr[] = {1, 2, 3, 4, 5};
int size = sizeof(arr) / sizeof(arr[0]);
cout << "Original array: ";
printArray(arr, size);
processArray(arr, size);
cout << "After doubling: ";
printArray(arr, size);
cout << "Sum: " << arraySum(arr, size) << endl;
int fixed[] = {10, 20, 30};
printFixedArray(fixed); // Template preserves size
}
void demonstrateMixedParameters() {
cout << "\n╔══════════════════════════════════════════════════════════════╗" << endl;
cout << "║ SECTION 7: Mixed Parameter Types ║" << endl;
cout << "╚══════════════════════════════════════════════════════════════╝" << endl;
vector<int> input = {5, -2, 10, -7, 3, 0, 8};
vector<int> output;
int errors;
cout << "Input: ";
printVector(input);
bool success = processData(input, output, &errors, 0);
cout << "Filtered (threshold=0): ";
printVector(output);
cout << "Errors: " << errors << ", Success: " << boolalpha << success << endl;
cout << "\nConfigured printing:" << endl;
printVectorConfigured(output); // Default config
PrintConfig cfg;
cfg.prefix = "Data: [";
cfg.suffix = "]";
cfg.showIndices = true;
printVectorConfigured(output, cfg);
}
// ============================================================
// MAIN FUNCTION
// ============================================================
int main() {
cout << "╔════════════════════════════════════════════════════════════════════╗" << endl;
cout << "║ C++ FUNCTION PARAMETERS EXAMPLES ║" << endl;
cout << "║ Understanding Different Parameter Passing Methods ║" << endl;
cout << "╚════════════════════════════════════════════════════════════════════╝" << endl;
demonstratePassByValue();
demonstratePassByReference();
demonstrateConstReference();
demonstratePassByPointer();
demonstrateDefaultArguments();
demonstrateArrayParameters();
demonstrateMixedParameters();
cout << "\n╔════════════════════════════════════════════════════════════════════╗" << endl;
cout << "║ Examples Complete! ║" << endl;
cout << "╚════════════════════════════════════════════════════════════════════╝" << endl;
return 0;
}