Skip to main content

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.

L1

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.
PartMeaningExample
Return typeWhat the function gives backint, double, void, string
NameHow you call itadd, printBill
ParametersInputs declared in the header(int a, int b)
BodyStatements inside { }return a + b;
CallUsing the functionadd(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, cout helpers via headers).
  • User-defined: you write them for your problem.
TypeMeaningExample / real-life
Library (built-in)Provided by C++ / headerssqrt(x), toupper(c) — calculator chip
User-definedWritten by the programmercalculateBill() — your shop logic
No return (void)Does work, returns nothingprintReceipt() — display only
With returnSends a value backint getBalance() — ask bank balance
No parametersNeeds no inputsvoid showMenu() — always same menu
With parametersNeeds inputsvoid greet(string name) — personalized
With params + returnInputs in, value outdouble area(double r) — formula
Inline (hint)Suggest expand at call siteTiny getters — micro tasks
OverloadedSame name, different paramsprint(int) / print(string)
RecursiveCalls itselffactorial(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).
FormCodeNotes
Prototypeint add(int, int);Declaration only
Prototype with namesint add(int a, int b);Names are documentation
Definitionint add(int a, int b) { return a+b; }Has a body
Calladd(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.
TermWhereExample
ParameterIn definition / prototypevoid pay(int amount)
ArgumentIn the callpay(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).
ScopeDeclared whereVisible whereLifetime
LocalInside a functionThat function onlyUntil function returns
BlockInside { } / loop / ifThat block onlyEnd of block
ParameterIn function headerThat function bodyUntil function returns
GlobalOutside all functionsFrom that point onward in the fileEnd 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.
NeedChooseExample
Compute a valueReturn type + returnint total(cart)
Only display / writevoidvoid printBill()
Modify caller’s dataReference paramsvoid swap(a, b)
Optional settingsDefault argumentsconnect(host, port=80)
Same action, different typesOverloadingarea(r) / area(l,w)
Declare before mainPrototypeint area(int);
L2

Advanced — Functions

const references and large objects

  • Prefer const string& / const vector& for 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)

  • inline suggests 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.
  • static on 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 x hides an outer x — 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-void functions 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.
  • return exits 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) vs grade(double gpa) for different inputs.
  • Config: connect(host, port = 443) uses a default secure port.
L3

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.).

L4

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;
}
L5

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.
L6

Practice Programs List

  1. Write prototypes and definitions for add, subtract, multiply, divide; call them from main.
  2. Create a void showWelcome() and an int getAge() that reads and returns age.
  3. Demonstrate pass by value vs reference by trying to update a marks total both ways.
  4. Write swap(int&, int&) and test it.
  5. Declare a global count and a local count in main — print both carefully (then refactor globals away).
  6. Use block scope inside an if to declare a temporary discount variable.
  7. Function with default argument: greet(name, title = "Friend").
  8. Overload max for two ints and two doubles.
  9. Overload print for int, double, and string.
  10. Write bool isEven(int n) and use it in a loop over an array.
  11. calcBill(itemsTotal, taxPercent = 18) with a default tax.
  12. Return two results using a pair: roots or minMax of two numbers.
  13. Refactor a long main into at least three well-named functions.
  14. Explain in comments the scope of each variable in a small sample program.