optional · CSS study notes
II.12 Functions & Parameter Passing
⬆️ P-I.II. Programming Fundamentals · Question Bank · Chapter II (2016–2026)
🧠
Remember: Declare → define → call; base case before recursion.
Start here — what you should be able to do
- Show prototype, definition and call in one answer.
- Trace copy, reference and pointer parameters precisely.
- Explain recursion, overloading, defaults and inline.
Reading order: foundation checks → full notes and examples → exam traps → self-test without notes → past-paper answers. All sections below remain part of the topic; code examples are kept in full.
Foundation checks
Function contract
- Inputs: parameter types and permitted values.
- Result: return type and meaning; use
voidwhen no value is returned. - Side effects: identify any caller-owned data the function changes.
- Precondition: for the simple power example, exponent n ≥ 0.
- Recursion: a reachable base case and progress toward it are both needed.
Overloading: return type alone cannot distinguish overloads.
Inline: inline substitution is not guaranteed; inline also has language-level definition rules. C++ working draft.
Value parameters: an ordinary scalar copy cannot change the caller's scalar, but a copied pointer/reference-like value may still reach shared objects.
1. Why Use Functions
- Modularity: breaks a large program into smaller, manageable pieces
- Reusability: write once, call many times
- Abstraction: caller only needs to know what a function does, not how
- Easier debugging/testing: each function can be tested in isolation
2. Anatomy of a Function
int add(int a, int b) // prototype/signature: return type, name, parameters
{
int sum = a + b; // function body
return sum; // return statement -- sends a value back to the caller
}
int main()
{
int result = add(3, 4); // function call, with arguments 3 and 4
}
- Function prototype/declaration: tells the compiler the function's name, return type, and parameter types before it's used —
int add(int, int); - Function definition: the actual body/implementation
- Function call: invokes the function with specific arguments
- Parameters (in the definition) vs Arguments (values passed at the call site) — a common terminology mix-up
- A function with return type
voidreturns no value;return;(with no value) is optional in that case
3. Standard Library vs User-Defined Functions
- Standard library functions: pre-built, reusable functions provided by the language (e.g.,
strlen(),sqrt()) - User-defined functions: programmer-written, promote modularity and reuse
4. Parameter Passing
- Pass by value: a copy of the argument is passed; changes inside the function do NOT affect the original variable
void increment(int x) { x++; } // caller's variable unchanged after this returns
- Pass by reference: the function receives a reference/alias to the original variable; changes DO affect the original
void increment(int &x) { x++; } // caller's variable IS changed (C++ reference parameter)
- Pass by pointer (C-style equivalent of reference): the function receives the address of the variable, and dereferences it to modify the original
void increment(int *x) { (*x)++; } // called as increment(&num);
5. Call by Value vs Call by Reference — C++ Deep Dive
Why it matters — the classic swap() example:
// Call by value -- does NOT work, only swaps local copies
void swapByValue(int a, int b)
{
int temp = a;
a = b;
b = temp;
} // 'a' and 'b' here are copies -- caller's variables are untouched
// Call by reference -- works correctly
void swapByReference(int &a, int &b)
{
int temp = a;
a = b;
b = temp;
} // 'a' and 'b' are aliases for the caller's actual variables
int main()
{
int x = 5, y = 10;
swapByValue(x, y);
cout << x << " " << y << endl; // still 5 10 -- unchanged
swapByReference(x, y);
cout << x << " " << y << endl; // now 10 5 -- actually swapped
}
const reference parameters — pass big objects cheaply and safely:
// Passing a large object BY VALUE copies the whole thing -- wasteful,
// and for a class it invokes the copy constructor (see the OOP notes)
void printRecord(Student s) { s.showdata(); }
// Passing BY CONST REFERENCE avoids the copy entirely, AND 'const'
// stops the function from accidentally modifying the caller's object
void printRecord(const Student &s) { s.showdata(); }
This const & pattern is the default choice in real C++ for passing any object bigger than a primitive type — cheap like a reference, safe like pass-by-value.
Comparison — all four parameter-passing mechanisms in C++:
| Mechanism | C++ syntax | Can modify original? | Copy made? |
|---|---|---|---|
| Call by value | void f(int x) | No | Yes — full copy |
| Call by reference | void f(int &x) | Yes | No |
Call by const reference | void f(const int &x) | No (compiler-enforced) | No |
| Pointer parameter by value | void f(int *x), called as f(&var) | Yes, through a valid *x | The pointer value is copied |
Link to OOP (frequently tested together):
- Passing a class object by value calls its copy constructor to build the local copy — expensive for large objects, and if the parameter's declared type is a base class while a derived object is passed, this is exactly how object slicing happens (see the Polymorphism page)
- Passing by reference or pointer avoids both problems: no copy constructor call, and no slicing, since the function operates on the real object through an alias/address
- Rule of thumb for CSS answers: pass built-in types (
int,char,double) by value; pass class/struct objects byconstreference unless the function is meant to modify the caller's object, in which case use a plain reference
6. Recursion
- A function that calls itself, with a base case that stops the recursion and a recursive case that moves toward it
int factorial(int n)
{
if (n == 0) return 1; // base case
return n * factorial(n - 1); // recursive case
}
- Every recursive call adds a new frame to the call stack; missing/incorrect base case causes infinite recursion and may exhaust available stack/storage
7. Other Function Features
- Default arguments (C++): a parameter can have a fallback value used when the caller omits it —
void greet(string name = "Guest"); - Function overloading (C++): multiple functions with the same name but different parameter lists, resolved at compile time
- inline: permits language-defined multiple-definition arrangements and suggests substitution; it does not force the compiler to inline calls.
8. 💻 Code Examples: C & C++
Pass by value vs by reference/pointer, plus recursion, run in one program — and the C++-only features (default arguments, overloading):
C:
#include <stdio.h>
void incByValue(int x) { x++; } // copy -- caller unaffected
void incByPointer(int *x) { (*x)++; } // address -- caller IS affected
int factorial(int n) { // recursion
if (n == 0) return 1; // base case
return n * factorial(n - 1); // recursive case
}
int main(void) {
int a = 5;
incByValue(a);
printf("after incByValue: %d\n", a); // still 5
incByPointer(&a);
printf("after incByPointer: %d\n", a); // now 6
printf("5! = %d\n", factorial(5)); // 120
return 0;
}
C++:
#include <iostream>
using namespace std;
void incByValue(int x) { x++; } // copy -- caller unaffected
void incByReference(int &x) { x++; } // C++ reference -- caller IS affected
int factorial(int n) {
if (n == 0) return 1;
return n * factorial(n - 1);
}
void greet(string name = "Guest") { // default argument (C++ only)
cout << "Hello, " << name << endl;
}
int add(int a, int b) { return a + b; } // function overloading (C++ only)
double add(double a, double b) { return a + b; }
int main() {
int a = 5;
incByValue(a);
cout << "after incByValue: " << a << endl; // still 5
incByReference(a);
cout << "after incByReference: " << a << endl; // now 6
cout << "5! = " << factorial(5) << endl; // 120
greet(); // uses default "Guest"
cout << add(2, 3) << " " << add(2.5, 3.5) << endl; // compiler picks the right overload
return 0;
}
9. MCQ Traps
- Pass by value never affects the caller's original variable; pass by reference/pointer can
- Parameters are the names in the function definition; arguments are the actual values supplied at the call — often confused but distinct terms
- Termination: a terminating recursive algorithm needs a reachable base case and progress toward it; otherwise recursion may continue until resources are exhausted.
- A function prototype ends with a semicolon and has no body; a function definition has a body and no trailing semicolon
- Function overloading is resolved by the compiler based on the number/type of parameters — return type alone cannot distinguish overloaded functions
- A reference parameter (
int &x) must be bound to a variable at the point of call and can never be reseated to refer to a different variable afterward — unlike a pointer, which can be reassigned to point elsewhere - Passing a class object by value silently invokes its copy constructor — a common hidden performance/exam-trap point; passing
const &avoids the copy (and avoids object slicing)
10. Self-Test Questions — with answers
Q1. Distinguish pass by value and pass by reference.
Answer
void value(int x) { x = 9; }changes only the local copy.void reference(int& x) { x = 9; }changes the caller's object.- Starting with a = 3, value(a) leaves 3; reference(a) leaves 9.
Q2. Distinguish a prototype from a definition.
Answer
- Prototype: declares name, return type and parameter types:
int add(int, int);. - Definition: supplies the body:
int add(int a, int b) { return a + b; }. - Both declarations must agree.
Q3. What two things make recursion terminate correctly?
Answer
- A reachable base case.
- A recursive step that makes progress toward it.
- Also state the input domain and any arithmetic limits.
Q4. Distinguish a parameter from an argument.
Answer
- In
int square(int x), x is the parameter. - In
square(5), 5 is the argument supplied by the caller.
Q5. What happens without a reachable base case?
Answer
- Recursion may continue without termination.
- Repeated calls can exhaust available stack/storage; a crash is a possible result, not a language guarantee.
Q6. Why does swap by value fail to change caller variables?
Answer
- It swaps two local copies.
- Reference parameters alias the caller's objects, so their assignments change those objects.
- Demonstrate using before/after values, not only a definition.
Q7. Why pass a large read-only object by const reference?
Answer
- It often avoids an unnecessary copy.
constprevents modifying that object through the parameter.- It does not make all aliased state globally immutable; choose parameter passing according to ownership and purpose.
- Differentiate pass by value from pass by reference with a short code example for each.
- What is the difference between a function prototype and a function definition?
- What two things must every correctly written recursive function have?
- Differentiate a parameter from an argument.
- What happens if a recursive function is missing its base case?
- Why does
swapByValue()fail to swap the caller's variables whileswapByReference()succeeds? - Why is
const Type&often preferred over passing a class object by value as a function parameter?
11. 📜 Past-Paper Questions & MCQs (CSS 2016–2026)
2016 · Paper-I · Q3(a) · 6 marks
Recall cue: State whether the quoted rate is monthly or annual; declare the prototype; define the calculation; call it from main.
Q. Define a function monthly_profit taking a percent profit rate and an investment amount (floats) and returning the monthly profit. Write the prototype, definition and a main program.
Answer — key points
#include <iostream>
using namespace std;
float monthlyProfit(float rate, float amount); // prototype
int main() {
float r, a;
cout << "Enter percent profit rate: "; cin >> r;
cout << "Enter investment amount: "; cin >> a;
cout << "Monthly profit: " << monthlyProfit(r, a);
return 0;
}
float monthlyProfit(float rate, float amount) { // definition
return (rate / 100) * amount;
}
- Check: (8/100) × 50000 = 4000.
2017 · Paper-I · Q3(b) · 6 marks
Recall cue: Check a ≠ 0; compute the discriminant; distinguish positive, zero and negative cases; call the function.
Q. Write a function to calculate the quadratic equation roots x = (−b ± √(b²−4ac)) / 2a using the math library.
Answer — key points
#include <iostream>
#include <cmath>
using namespace std;
void quadratic(float a, float b, float c) {
float d = b * b - 4 * a * c;
if (a == 0) { cout << "Not a quadratic equation"; return; }
if (d < 0) { cout << "Roots are complex"; return; }
cout << "The values of x are " << (-b + sqrt(d)) / (2 * a)
<< ", " << (-b - sqrt(d)) / (2 * a);
}
int main() {
float a, b, c;
cout << "Enter value of a: "; cin >> a;
cout << "Enter value of b: "; cin >> b;
cout << "Enter value of c: "; cin >> c;
quadratic(a, b, c);
}
- Check: a = 1, b = 2, c = 1 gives −1, −1.
2019 · Paper-I · Q3(b) · 5 marks
Recall cue: Compare copy versus alias; show caller values after a function call; distinguish a reference parameter from a copied pointer.
Q. What is the difference between call by value and call by reference?
Answer — key points
| Basis | Call by value | Call by reference |
|---|---|---|
| What is passed | A copy of the argument | The address or an alias of the argument |
| Effect on caller's variable | None | Changes are visible to the caller |
| Memory | Extra copy is made | No copy, so efficient for large objects |
| Syntax | void f(int x) | void f(int &x) or void f(int *x) |
void swapV(int a, int b) { int t = a; a = b; b = t; } // caller unchanged
void swapR(int &a, int &b) { int t = a; a = b; b = t; } // caller swapped
2021 · Paper-I · Q5(b) · 6 marks
Recall cue: Java copies the reference value: object mutation is visible, parameter reassignment does not replace the caller's reference.
Q. What is pass by value and pass by reference? Can we pass an object as a parameter to a method in Java?
Answer — key points
- Pass by value: a copy of the argument is passed, so changes inside the method do not affect the original.
- Pass by reference: the method works on the original variable (in C++ through
&or pointers). - Java: yes, an object can be passed as a parameter. Java passes the reference to the object by value, so the method can change the object's fields and the caller sees the change. Reassigning the parameter to a new object does not affect the caller's reference.
2022 · Paper-I · Q6(a) · 8 marks
Recall cue: State n ≥ 0; base case power(k,0)=1; reduce n at each call; discuss overflow limits.
Q. Complete the recursive function int power(int k, int n) to calculate kⁿ without library functions.
Answer — key points
int power(int k, int n) {
if (n == 0) return 1; // base case
return k * power(k, n - 1); // recursive case
}
- Optional faster version: for even n, compute
p = power(k, n/2)and returnp * p(time O(log n)).
MCQs
2025 P-I · Q15. What is the output of the following code? int a = 40; int* ptr = &a; int& ref = *ptr; ref = 60; cout << a;
- (A) 40
- (B) 60 ✅
- (C) Error
- (D) None of these
- Answer: (B) 60.
- Step by step:
ptr = &a, so*ptris the variableaitself.int& ref = *ptrmakesrefanother name (alias) fora.ref = 60therefore stores 60 ina, andcout << aprints 60.
- Why not the others: the code is valid, so there is no error, and
ais changed through the alias, so it is not 40.
2026 P-I · Q7. A function needs to modify an input variable. How should the parameter be passed?
- (A) By value
- (B) By reference ✅
- (C) By pointer
- (D) None of these
- Answer: (B) By reference.
- Why: pass by value gives the function only a copy, so the caller's variable cannot change. Passing by reference lets the function work on the original variable. (A pointer would also work, but "by reference" is the standard C++ answer and the cleaner syntax.)
Technical accuracy notes
- A C++ reference parameter aliases the caller's object.
- A pointer parameter is itself passed by value unless declared as a reference to a pointer
- it can still modify the pointed-to object.
- Java passes all arguments by value, including copied object references.
- For the monthly-profit question, specify whether the rate is monthly or annual
- the older notes disagree about dividing by 12.
Recall check and coverage
- Explain the three learning outcomes at the top without looking.
- Reproduce one example or trace and test a boundary case.
- Answer each self-test, then compare with the key.
- Attempt each recorded past-paper task on this page.
Recorded written references: 2016 · Paper-I · Q3(a) · 6 marks; 2017 · Paper-I · Q3(b) · 6 marks; 2019 · Paper-I · Q3(b) · 5 marks; 2021 · Paper-I · Q5(b) · 6 marks; 2022 · Paper-I · Q6(a) · 8 marks
Evidence limit: this page preserves the question records found in your Notion notes. Disputed labels and questions not checked against original PDFs remain flagged in the Question Bank; this is not a claim of exhaustive original-paper verification.