Functions
Functions
Complete lesson for Functions using LEARNCODEGURU’s 6-level learning model — from basics to advanced practice, with C++ OOP and STL where relevant.
Basics — Functions
Section: Functions. C++ functions — types, prototypes, parameters, scope of variables, overloading, and real-life examples.
What is a function?
- A **function** is a named block of code that does a specific job and can be **called** from other places.
- Parts: **name**, **parameters** (inputs), **return type** (output type), and **body** (statements).
- **Real-life analogy:** a washing machine — you put clothes in (arguments), press start (call), get clean clothes (return / side effect).
- **Real-life analogy:** ATM withdraw — input amount + PIN, output cash / message.
- Benefits: reuse, clearer programs, easier testing, divide big problems into steps.
| Part | Meaning | Example |
|---|---|---|
| Return type | What the function gives back | int, double, void, string |
| Name | How you call it | add, printBill |
| Parameters | Inputs declared in the header | (int a, int b) |
| Body | Statements inside { } | return a + b; |
| Call | Using the function | add(2, 3); |
#include <iostream>
using namespace std;
int add(int a, int b) {
return a + b;
}
int main() {
cout << add(10, 20) << "\n"; // 30
return 0;
} Types of functions
- Classify functions by **who wrote them**, by **return**, and by **parameters**.
- Library / built-in: already available (
sqrt,strlen,couthelpers via headers). - User-defined: you write them for your problem.
| Type | Meaning | Example / real-life |
|---|---|---|
| Library (built-in) | Provided by C++ / headers | sqrt(x), toupper(c) — calculator chip |
| User-defined | Written by the programmer | calculateBill() — your shop logic |
No return (void) | Does work, returns nothing | printReceipt() — display only |
| With return | Sends a value back | int getBalance() — ask bank balance |
| No parameters | Needs no inputs | void showMenu() — always same menu |
| With parameters | Needs inputs | void greet(string name) — personalized |
| With params + return | Inputs in, value out | double area(double r) — formula |
| Inline (hint) | Suggest expand at call site | Tiny getters — micro tasks |
| Overloaded | Same name, different params | print(int) / print(string) |
| Recursive | Calls itself | factorial(n) — see Recursion lesson |
Function prototype (declaration)
- A **prototype** (declaration) tells the compiler the function’s **name**, **parameter types**, and **return type** — before it is used.
- Syntax:
returnType name(parameterTypes);— ends with a **semicolon**, no body. - Needed when you call a function **above** its full definition (common: prototypes at top,
main, then definitions). - Parameter **names** in the prototype are optional; types are required.
- **Real-life analogy:** a restaurant menu lists dishes (prototype) before the kitchen cooks them (definition).
| Form | Code | Notes |
|---|---|---|
| Prototype | int add(int, int); | Declaration only |
| Prototype with names | int add(int a, int b); | Names are documentation |
| Definition | int add(int a, int b) { return a+b; } | Has a body |
| Call | add(2, 3); | Uses arguments |
#include <iostream>
#include <string>
using namespace std;
// Prototypes (declarations)
int add(int a, int b);
void greet(string name);
int main() {
greet("Ravi");
cout << add(5, 7) << "\n";
return 0;
}
// Definitions
int add(int a, int b) {
return a + b;
}
void greet(string name) {
cout << "Hello, " << name << "!\n";
} Function definition and call
- **Definition** = header + body with the actual statements.
- **Call** = use the name with arguments in
(); for returning functions, use the result (print, assign, or pass on). - Arguments must match parameter types (or convert safely). Order matters.
- A function can call other functions — build programs like Lego bricks.
#include <iostream>
using namespace std;
double circleArea(double r) {
return 3.14159 * r * r;
}
int main() {
double radius = 5;
double a = circleArea(radius); // call
cout << "Area = " << a << "\n";
return 0;
} Parameters vs arguments
- **Parameters** are variables in the function definition (
int a, int b). - **Arguments** are the actual values you pass at the call (
add(10, 20)). - **Real-life:** parameter = “slot for amount” on an ATM screen; argument = the ₹500 you type.
| Term | Where | Example |
|---|---|---|
| Parameter | In definition / prototype | void pay(int amount) |
| Argument | In the call | pay(500); |
Pass by value vs pass by reference
- **Pass by value:** function gets a **copy**. Changing the parameter does not change the caller’s variable.
- **Pass by reference (
type&):** function uses an **alias**. Changes affect the caller’s variable. - Use reference to modify inputs (swap) or avoid copying large objects (
const string&). - **Real-life value:** giving a photocopy of a form — edits on the copy don’t change the original.
- **Real-life reference:** editing the shared Google Doc — everyone sees the change.
#include <iostream>
using namespace std;
void setByValue(int x) { x = 100; }
void setByRef(int& x) { x = 100; }
void swap(int& a, int& b) {
int t = a; a = b; b = t;
}
int main() {
int n = 5;
setByValue(n);
cout << n << "\n"; // still 5
setByRef(n);
cout << n << "\n"; // 100
int a = 1, b = 2;
swap(a, b);
cout << a << " " << b << "\n"; // 2 1
return 0;
} Scope of variables
- **Scope** = where a variable’s name is visible and usable.
- **Local (function) scope:** declared inside a function — lives until that function ends.
- **Block scope:** declared inside
{ }(if/loop/block) — visible only in that block. - **Parameter scope:** parameters are local to the function.
- **Global scope:** declared outside all functions — visible from declaration to end of file (use sparingly).
- Inner names can **shadow** outer names — confusing; avoid when possible.
- **Real-life:** a classroom whiteboard (local) vs a notice board in the corridor (global).
| Scope | Declared where | Visible where | Lifetime |
|---|---|---|---|
| Local | Inside a function | That function only | Until function returns |
| Block | Inside { } / loop / if | That block only | End of block |
| Parameter | In function header | That function body | Until function returns |
| Global | Outside all functions | From that point onward in the file | End of program |
#include <iostream>
using namespace std;
int counter = 0; // global (prefer to avoid)
void bump() {
int step = 1; // local
counter += step;
}
int main() {
int x = 10; // local to main
if (x > 0) {
int y = 20; // block scope
cout << x + y << "\n";
}
// y is not visible here
bump();
cout << "counter = " << counter << "\n";
return 0;
} Default arguments
- You can give parameters default values:
void f(int x = 0); - Defaults must be at the **end** of the parameter list (right side).
- Callers may omit those arguments — the defaults are used.
- **Real-life:** online order — shipping = “Standard” unless you choose Express.
#include <iostream>
using namespace std;
int power(int base, int exp = 2) {
int r = 1;
for (int i = 0; i < exp; i++) r *= base;
return r;
}
int main() {
cout << power(5) << "\n"; // 25 (exp defaults to 2)
cout << power(2, 3) << "\n"; // 8
return 0;
} Function overloading
- Same function **name**, different **parameter lists** (number or types).
- Return type alone is **not** enough to overload.
- Compiler picks the best match from the call arguments.
- **Real-life:** “print” can mean print a number or print a ticket — same verb, different inputs.
#include <iostream>
#include <string>
using namespace std;
void show(int n) { cout << "int: " << n << "\n"; }
void show(double d) { cout << "double: " << d << "\n"; }
void show(const string& s) { cout << "string: " << s << "\n"; }
int main() {
show(10);
show(3.14);
show("Hello");
return 0;
} Which function style should you use?
- Match the shape of the job — keep names verb-like and clear.
| Need | Choose | Example |
|---|---|---|
| Compute a value | Return type + return | int total(cart) |
| Only display / write | void | void printBill() |
| Modify caller’s data | Reference params | void swap(a, b) |
| Optional settings | Default arguments | connect(host, port=80) |
| Same action, different types | Overloading | area(r) / area(l,w) |
Declare before main | Prototype | int area(int); |
Advanced — Functions
const references and large objects
- Prefer
const string&/const vectorfor read-only inputs — no copy, cannot modify.& - Use non-const reference only when the function must update the caller’s object.
- Pointers can also pass/modify, but references are clearer for “must refer to an object”.
#include <iostream>
#include <string>
using namespace std;
int scoreLen(const string& name) { // no copy
return static_cast<int>(name.size());
}
int main() {
string s = "LearnTechGuru";
cout << scoreLen(s) << "\n";
return 0;
} Inline, static, and linkage (overview)
inlinesuggests the compiler may substitute the body at the call site (hint, not a guarantee).- Good for tiny functions; modern compilers often inline without the keyword.
staticon a free function gives **internal linkage** (file-local) in C++.- Put prototypes in headers, definitions in
.cpp(except templates / inline in headers).
Scope, lifetime, and shadowing (deep)
- Scope ≠ lifetime always, but for ordinary locals they end together when the block ends.
- Globals last for the whole program — harder to test and reason about; prefer passing data as parameters.
- Shadowing: an inner
int xhides an outerx— legal but error-prone. - Declare variables in the smallest scope that needs them (C++ allows mid-block declarations).
int x = 1; // global
void f() {
int x = 2; // shadows global
cout << x << "\n"; // 2
}
// After f ends, local x is gone; global still 1 Return rules and multiple results
- Non-
voidfunctions should return a value on every path (compilers warn otherwise). - To return multiple values: use references/out-params, a
struct/pair/tuple, or a small class. returnexits the function immediately — code after it in that path does not run.
#include <utility>
using namespace std;
pair<int, int> minMax(int a, int b) {
if (a < b) return {a, b};
return {b, a};
} Real-life function designs
- E-commerce:
double calcTotal(items, coupon)returns payable amount;void printInvoice(...)displays. - Banking:
bool withdraw(Account& a, int amount)modifies balance by reference, returns success. - School: overloaded
grade(int marks)vsgrade(double gpa)for different inputs. - Config:
connect(host, port = 443)uses a default secure port.
Tricky Interview Points
Q1) What is a function in C++?
Answer A named reusable block of code with a return type, optional parameters, and a body. It is invoked by a call with arguments.
Q2) What is a function prototype?
Answer A declaration of the function’s return type, name, and parameter types (no body), ending with a semicolon. It lets you call the function before its definition appears.
Q3) Difference between declaration and definition?
Answer Declaration (prototype) introduces the signature. Definition provides the body with statements that implement the function.
Q4) What are types of functions?
Answer Common classifications: library vs user-defined; void vs returning; with/without parameters; overloaded; recursive; optionally inline.
Q5) Parameters vs arguments?
Answer Parameters are the variables in the function definition. Arguments are the actual values passed at the call site.
Q6) Pass by value vs pass by reference?
Answer By value passes a copy; changes inside do not affect the caller. By reference (type&) aliases the caller’s object; changes do affect it.
Q7) What is scope of a variable?
Answer The region of the program where the variable’s name is visible — local/function, block, parameter, or global.
Q8) What are local and global variables?
Answer Local variables are declared inside a function/block and exist only there. Global variables are declared outside functions and are visible across the file from their declaration (use carefully).
Q9) What are default arguments?
Answer Parameter defaults used when the caller omits those arguments. Defaults must be trailing (rightmost) parameters.
Q10) What is function overloading?
Answer Multiple functions with the same name but different parameter lists. Return type alone cannot distinguish overloads.
Q11) Can two overloaded functions differ only by return type?
Answer No. The parameter lists must differ in number or types (or both).
Q12) Why prefer const T& for large read-only inputs?
Answer Avoids copying the object while preventing modification — efficient and safe for strings, vectors, etc.
Q13) What does void mean as a return type?
Answer The function does not return a value to the caller; it performs an action (print, update via references, etc.).
Simple Programs
Prototype + definition + call
#include <iostream>
using namespace std;
int square(int n); // prototype
int main() {
cout << square(6) << "\n";
return 0;
}
int square(int n) { // definition
return n * n;
} void vs returning function
#include <iostream>
using namespace std;
void showMenu() {
cout << "1. Tea\n2. Coffee\n";
}
int priceOf(int choice) {
if (choice == 1) return 20;
if (choice == 2) return 30;
return 0;
}
int main() {
showMenu();
cout << "Coffee costs " << priceOf(2) << "\n";
return 0;
} Pass by value vs reference
#include <iostream>
using namespace std;
void addBonusValue(int salary) { salary += 1000; }
void addBonusRef(int& salary) { salary += 1000; }
int main() {
int pay = 20000;
addBonusValue(pay);
cout << pay << "\n"; // 20000
addBonusRef(pay);
cout << pay << "\n"; // 21000
return 0;
} Scope — local vs global
#include <iostream>
using namespace std;
int tickets = 0; // global counter (demo only)
void book() {
int seat = 12; // local
tickets++;
cout << "Booked seat " << seat << "\n";
}
int main() {
book();
book();
cout << "Total tickets = " << tickets << "\n";
return 0;
} Default arguments — shipping
#include <iostream>
#include <string>
using namespace std;
void ship(const string& item, string mode = "Standard") {
cout << "Shipping " << item << " via " << mode << "\n";
}
int main() {
ship("Book");
ship("Phone", "Express");
return 0;
} Overloading — area
#include <iostream>
using namespace std;
double area(double r) { return 3.14159 * r * r; }
double area(double l, double w) { return l * w; }
int main() {
cout << area(5) << "\n";
cout << area(4, 6) << "\n";
return 0;
} Bank withdraw with reference
#include <iostream>
using namespace std;
bool withdraw(int& balance, int amount) {
if (amount <= 0 || amount > balance) return false;
balance -= amount;
return true;
}
int main() {
int bal = 5000;
if (withdraw(bal, 1200))
cout << "OK, left " << bal << "\n";
else
cout << "Failed\n";
return 0;
} Problem Solving Tricks
- Write a clear verb name: calculateTotal, printBill, isValid — not doStuff.
- Put prototypes above main when definitions are below.
- One function ≈ one job; split large functions.
- Prefer parameters over globals for data flow.
- Use const T& for read-only large objects.
- Use T& only when you intentionally modify the caller’s variable.
- Default arguments only at the trailing end of the parameter list.
- Overload by parameters, not by return type alone.
- Declare variables in the smallest useful scope.
- Always return a value from every path in a non-void function.
- Keep parameter lists short; group related data into a struct when needed.
- Match prototype types exactly with the definition.
Practice Programs List
- Write prototypes and definitions for add, subtract, multiply, divide; call them from main.
- Create a void showWelcome() and an int getAge() that reads and returns age.
- Demonstrate pass by value vs reference by trying to update a marks total both ways.
- Write swap(int&, int&) and test it.
- Declare a global count and a local count in main — print both carefully (then refactor globals away).
- Use block scope inside an if to declare a temporary discount variable.
- Function with default argument: greet(name, title = "Friend").
- Overload max for two ints and two doubles.
- Overload print for int, double, and string.
- Write bool isEven(int n) and use it in a loop over an array.
- calcBill(itemsTotal, taxPercent = 18) with a default tax.
- Return two results using a pair: roots or minMax of two numbers.
- Refactor a long main into at least three well-named functions.
- Explain in comments the scope of each variable in a small sample program.