D.
C++ – Nesting, Recursion & Command-Line Arguments
– Nesting of Functions
1. Introduction to Function Nesting
Nesting means placing one function inside another.
But in C++, functions cannot be defined inside other functions.
However, functions can be called inside another function, and this is called:
➤ Nesting of Function Calls
It means calling one function from within the body of another function.
1.1 Why Nesting of Functions Is Needed?
1. Modularity:
Break complex operations into small functions.
2. Code Reusability:
A function can be reused by many others.
3. Better Organization:
Each function handles its own task.
4. Improved Readability:
Programs become easier to maintain.
1.2 Simple Example of Nested Function Calls
int sum(int a, int b) {
return a + b;
int square(int x) {
return x * x;
int compute(int a, int b) {
return square(sum(a, b)); // nesting
int main() {
cout << compute(2, 3);
Explanation
sum(a, b) runs first
its result is passed to square()
nested function call performs combined operation
1.3 Advantages of Nesting
✔ Reduces code duplication
✔ Allows building complex operations from smaller ones
✔ Improves modular design
✔ Encourages function reuse
1.4 Disadvantages of Nesting
✖ Hard to debug if too many layers
✖ Deep nesting reduces readability
✖ Execution order must be understood clearly
2 – Advanced Nesting Concepts
2.1 Multiple-Level Nesting
Example:
int f1(int x) { return x + 1; }
int f2(int x) { return f1(x) * 2; }
int f3(int x) { return f2(x) - 3; }
int main() {
cout << f3(5); // f3 calls f2 → f1
Here:
f3() → calls f2()
f2() → calls f1()
This is called multi-level nesting.
2.2 Nested Calls in Expressions
You can nest function calls inside arithmetic expressions:
result = abs(pow(x, 3) - sqrt(y));
2.3 Nesting with Library Functions
Example:
double ans = sqrt(pow(3, 2) + pow(4, 2));
2.4 Key Points for Exams
C++ does not allow nested definitions.
Nesting refers only to nested function calls.
Useful for step-by-step processing.
3 – Recursion
3.1 What is Recursion?
Recursion is a technique where a function calls itself directly or indirectly to solve a problem.
3.2 Structure of a Recursive Function
A recursive function always contains two parts:
1. Base Case (Termination Condition)
2. Recursive Case (Function calling itself)
General Form:
return_type function(parameters) {
if (base_condition)
return value; // base case
else
return function(modified_parameters); // recursive call
3.3 Example: Factorial Using Recursion
int factorial(int n) {
if (n == 0)
return 1; // base case
return n * factorial(n - 1); // recursive case
3.4 How Recursion Works? (Call Stack)
To compute factorial(4):
factorial(4)
→ 4 * factorial(3)
→ 3 * factorial(2)
→ 2 * factorial(1)
→ 1 * factorial(0)
→ returns 1
Then results unwind backwards.
3.5 Types of Recursion
1. Direct Recursion
Function calls itself directly.
void f() { f(); }
2. Indirect Recursion
Function A calls B, and B calls A.
void A() { B(); }
void B() { A(); }
3. Tail Recursion
Recursive call is the last statement.
4. Head Recursion
Recursive call occurs before any processing.
4 – Advantages & Disadvantages of Recursion
4.1 Advantages
✔ Simpler code for problems that are naturally recursive
✔ Reduces programming effort
✔ Useful for implementing divide-and-conquer algorithms
4.2 Disadvantages
✖ Higher memory usage (stack frames)
✖ Slower due to repeated function calls
✖ Risk of stack overflow
✖ Hard to debug if recursion depth is large
4.3 Applications of Recursion
1. Mathematical Computations
Factorial
Fibonacci
Power function
2. Divide-and-Conquer Algorithms
Quick sort
Merge sort
Binary search
3. Tree and Graph Traversals
Preorder, Inorder, Postorder
DFS (Depth First Search)
4.4 Example: Fibonacci Using Recursion
int fib(int n) {
if (n <= 1)
return n;
return fib(n - 1) + fib(n - 2);
4.5 When Should Recursion NOT Be Used?
❌ When performance is critical
❌ When iteration is simpler
❌ When stack memory is limited
❌ For very deep levels of computation
PAGE 5 – Command-Line Arguments
5.1 What are Command-Line Arguments?
Command-line arguments allow passing values to the program when the program is executed from the
terminal/command prompt.
These inputs are not taken using cin.
Instead, they are passed along with the execution command.
5.2 Syntax of main() with Command-Line Arguments
int main(int argc, char *argv[])
Meaning of Parameters
argc → Argument Count
(Number of arguments passed)
argv[] → Argument Vector
(Array of strings storing actual arguments)
5.3 Example: Print All Command-Line Arguments
Command to run:
./[Link] hello world
Code:
#include <iostream>
using namespace std;
int main(int argc, char *argv[]) {
for (int i = 0; i < argc; i++)
cout << argv[i] << endl;
Output:
./[Link]
hello
world
5.4 Why Do We Use Command-Line Arguments?
✔ To pass data at runtime
✔ Useful in automation
✔ Required for file handling programs
✔ Used in real-world software like compilers, interpreters
6 – Advanced Details & Summary
6.1 Converting Command-Line Arguments
All arguments in argv[] are strings.
To convert them:
int x = atoi(argv[1]);
float y = atof(argv[2]);
Using <cstdlib> library.
6.2 Practical Use Cases
1. File Handling
./program [Link] [Link]
2. Mathematical Calculators
./calc 20 5 add
3. Compiler Behavior
gcc -o program file.c
4. Automation Scripts
6.3 Differences: Nesting vs Recursion vs Command-Line Arguments
Concept. Meaning. Key Feature
Nesting. Calling functions inside functions Multi-level calls
Recursion. Function calling itself. Solves repetitive/complex tasks
Command-Line Args Passing input from terminal. Input supplied at program start
6.4 Final Exam-Ready Summary
Nesting
Calling one function inside another
Increases modularity and reusability
C++ does not allow nested function definitions
Recursion
A function calling itself
Needs base case + recursive case
Used in trees, sorting, math algorithms
Beware of stack overflow
Command-Line Arguments
Inputs passed through terminal
main() becomes:
int main(int argc, char *argv[])
argc = number of arguments
argv[] = arguments as strings
📘 Arrays as Function Arguments —
1 — INTRODUCTION TO ARRAYS AS FUNCTION ARGUMENTS
1. What Are Array Arguments?
In C++, an array can be passed to a function so the function can operate on a group of values together.
Example: sorting numbers, calculating average, searching an element, matrix operations, etc.
Unlike normal variables, an array cannot be passed as a whole copy, because arrays are always treated
as addresses when passed to functions.
2. Why Pass Arrays to Functions?
To avoid writing repetitive code
To modularize programs
To operate on large collections of data
To reduce memory usage (only address is passed, not full data)
3. Array Passing Mechanism
In C++, arrays are implicitly passed by address (similar to call-by-reference).
Thus, any change inside the function directly affects the original array.
4. Syntax of Passing an Array
Function Declaration
void display(int arr[], int n);
Function Call
display(a, 5);
Function Definition
void display(int arr[], int n) {
for(int i = 0; i < n; i++)
cout << arr[i] << " ";
2 — HOW ARRAYS ARE PASSED INTERNALLY
1. Name of the Array = Base Address
When you write:
display(a, 5);
The value actually passed is:
& a[0] // address of first element
2. Arrays Are Equivalent to Pointers in Function Parameters
These three declarations are equivalent:
void func(int arr[]);
void func(int arr[10]);
void func(int *arr);
❗ Size inside brackets in function parameter does NOT matter.
3. Why Size Is Passed Separately?
Because inside the function,
arr[] becomes just a pointer.
The function does not know the array length.
Hence, we pass size as another parameter.
4. Diagram: Memory Passing
Main Function Called Function
-----------------------------------------------------------
int a[5] = {1,2,3,4,5}; ---> arr → address of a[0]
arr[0], arr[1] ...
Thus, arr inside the function refers to the same memory as a in main.
3 — EXAMPLES & TYPES OF ARRAY PASSING
1. One-Dimensional Array Example
void increment(int arr[], int n) {
for(int i=0; i<n; i++)
arr[i]++; // modifies original array
int main() {
int a[3] = {1,2,3};
increment(a, 3);
// a becomes {2,3,4}
Key Point:
Since arrays are passed by address, changes remain permanent.
2. Two-Dimensional Arrays as Arguments
Syntax Requirement
When passing 2D arrays, second dimension must be fixed:
void display(int arr[][10], int rows)
OR
void display(int (*arr)[10], int rows)
Example
void printMatrix(int m[][3], int r) {
for(int i=0;i<r;i++) {
for(int j=0;j<3;j++)
cout << m[i][j] << " ";
cout << endl;
Why second size must be given?
Compiler needs total bytes to compute address of m[i][j].
Formula:
Address = Base + (i * columns + j) * sizeof(int)
So columns = must be known.
4 — DIFFERENT METHODS OF PASSING ARRAYS TO FUNCTIONS
Method 1: Pass by Pointer
void func(int *p, int n);
Same as passing array.
Method 2: Pass by Reference to Entire Array
(Useful for preventing decay to pointer)
void func(int (&arr)[5]) {
// arr is an actual array of size 5
Calling:
int a[5];
func(a);
Advantages
Compiler checks size
Prevents incorrect array sizes
Method 3: Passing a Portion of Array
You can pass:
func(a + 2, 5); // starting from index 2
Inside function: arr[0] will refer to original a[2].
Method 4: Passing Arrays Using std::array<> (Modern C++)
void func(std::array<int,5> arr);
Passed by value (copy)
Or by reference:
void func(const std::array<int,5> &arr);
Method 5: Passing Arrays Using vector<int>
Most flexible and recommended in modern C++.
void display(const vector<int> &v);
Advantages
Size is already known
Dynamic resizing possible
Safe and easy
5 — IMPORTANT CONCEPTS, PITFALLS
1. Array Decay
When passed to a function:
int arr[]
↓ decays to
int * pointer
So inside function:
Size cannot be known
sizeof(arr) gives size of pointer, not array
2. Modifying Array in Functions
Example:
void fun(int arr[]) {
arr[1] = 999;
Changes reflect in main.
3. Common Interview Question
Q: Can a function return an array?
Directly NO, but we can:
Return pointer to array
Return vector
Return std::array
Return dynamically allocated array
Return struct/class containing array
4. Advantages of Passing Arrays to Functions
✔ Saves memory
✔ Supports modular programming
✔ Direct access to large data
✔ Efficient for algorithms (sorting, searching)
5. Limitations
❌ Cannot know size inside function
❌ Risk of modifying original array unintentionally
❌ 2D array second dimension must be fixed
❌ No bounds checking (risk of accessing illegal index)
6. — Important Definitions
Array Passing
Method of giving the address of first element to a function.
Base Address
Starting location of the array (&arr[0]).
Array Decay
Array converting to pointer when passed to a function.
Call-by-Reference Behavior
Array changes inside function reflect outside.
Pointer Arithmetic
Used to iterate through array elements via pointer.
📘 Pointers in C++: Basics, Operators, Arithmetic, Pointers with Functions & Strings
1 — INTRODUCTION TO POINTERS
1. What Is a Pointer?
A pointer is a variable that stores the memory address of another variable.
Unlike normal variables that store data (like 10, 3.5, 'A'), a pointer stores where the data is located in
memory.
Example:
int a = 10;
int *p = &a;
Here:
a stores 10
p stores the address of a
2. Why Use Pointers?
Pointers are essential in C++ for:
Efficient memory management
Dynamic memory allocation (new, delete)
Passing large data to functions without copying
Building data structures (linked lists, trees, graphs)
Returning multiple values from functions
Working with arrays, strings, and files
3. Pointer Declaration
int *p;
float *q;
char *c;
Asterisk * signifies “pointer to”.
4. & Address-of Operator
Used to get the address of a variable:
int x = 20;
cout << &x;
Prints something like:
0x61ff0c
5. Pointer Initialization
int x = 5;
int *p = &x;
6. Null Pointer
Used to represent empty or invalid address:
int *ptr = nullptr; // modern C++
2 — POINTER OPERATORS (* and &)
1. Address-of Operator (&)
Returns the memory location of a variable.
Example:
int a = 5;
cout << &a;
2. Dereference Operator (*)
Used to access or modify the value stored at the address.
int a = 5;
int *p = &a;
cout << *p; // prints 5
*p = 20; // modifies a
After modification: a = 20
3. Pointer vs Normal Variable
Normal Variable Pointer
Stores value. Stores address
Direct access. Indirect access using *
4. Pointer to Pointer (double pointer)
A pointer that stores address of another pointer:
int a = 10;
int *p = &a;
int **q = &p;
Access: **q → value of a
5. Void Pointer
Special pointer that can store address of any type:
void *p;
int x=10;
p = &x;
Cannot be directly dereferenced without typecasting.
3 — POINTER ARITHMETIC
Pointer arithmetic is allowed only on: ✔ arrays
✔ dynamically allocated memory
Not allowed on: ❌ void pointers
❌ structures (without arrays)
1. Increment Operator (p++)
Increases pointer to point to next memory block.
int a[3]={10,20,30};
int *p=a;
p++; // moves to next integer (4 bytes ahead)
Memory jumps according to data type:
int → +4 bytes
char → +1 byte
float → +4 bytes
double → +8 bytes
2. Decrement Operator (p--)
Moves to previous element.
3. Addition / Subtraction (p + n, p - n)
p = p + 2; // jumps 2 integers ahead
4. Pointer Difference
int diff = p2 - p1;
Returns the number of elements between them.
5. Comparison of Pointers
if(p1 > p2) { ... }
Valid only if both pointers refer to same array.
6. Pointer Arithmetic on Character Pointers
char s[] = "HELLO";
char *p = s;
p++; // moves to next character
Pointer Arithmetic Example Table
Operation Meaning
p++ Move to next element
p-- Move to previous element
p+n Skip n elements
p2-p1 Gives element difference
4 — POINTERS & FUNCTIONS
Pointers make functions more powerful and efficient.
1. Passing Variables by Pointer (Call-by-Reference)
Example: Swapping values
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
Call:
swap(&x, &y);
✔ Changes reflect outside the function.
2. Pointers as Function Arguments
General syntax
void func(int *ptr);
Passing:
func(&x);
3. Pointers Returning Values From Functions
Returning dynamic memory
int* create() {
int *p = new int;
*p = 50;
return p;
4. Pointer to Function (Advanced Concept)
Function pointer stores address of a function:
int add(int a, int b) { return a + b; }
int (*fptr)(int, int) = add;
cout << fptr(5, 6);
5 — POINTERS & ARRAYS
1. Relation Between Arrays and Pointers
Array name is a constant pointer to its first element.
int a[5];
int *p = a; // same as &a[0]
2. Pointer Iteration Through Array
int a[]={1,2,3};
int *p=a;
for(int i=0;i<3;i++)
cout<<*(p+i);
3. Array of Pointers
int *arr[3];
Used mainly with strings.
4. Pointer to Array
int (*p)[5];
Pointer that points to an entire array.
5. Dynamic Arrays Using Pointers
int *p = new int[10];
6 — POINTERS & STRINGS
Strings in C++ as char arrays end with '\0'.
1. Character Pointer
char *s = "Hello";
s points to constant string literal stored in read-only memory.
2. Traversing String Using Pointer
char s[] = "World";
char *p = s;
while(*p) {
cout << *p;
p++;
3. Difference: char *s vs. char s[]
char *s = "abc" char s[] = "abc"
String literal stored in read-only memory Stored in stack/array
Cannot modify Can modify
Pointer to constant Array
4. Pointers to String Arrays
char *names[] = {"Ram","Shyam","Geeta"};
Each element is a pointer to a string.
5. Functions Handling Strings with Pointers
Example: String length
int length(char *s) {
int count = 0;
while(*s++) count++;
return count;
7 — IMPORTANT DIAGRAMS, NOTES, & VIVA QUESTIONS
1. Pointer Diagram
For:
int x=10;
int *p=&x;
Memory:
-------------------
x : 10 (address: 1000)
p : 1000 (address: 2000)
Access:
p → 1000
*p → 10
2. Common Pointer Errors
❌ Using uninitialized pointer
❌ Dereferencing null pointer
❌ Pointer going out of bounds (dangerous)
❌ Using freed (deleted) pointer
❌ Mixed memory allocation (new/delete vs malloc/free)
3. Advantages of Pointers
✔ Faster processing
✔ Efficient memory use
✔ Required for dynamic structures
✔ Allow call-by-reference
✔ Enable pointer arithmetic
✔ Work directly with arrays & strings
4. Disadvantages
❌ Hard to debug
❌ Pointer misuse leads to crashes
❌ Memory leaks if not freed
❌ Dangling pointers
5. Short Viva Questions
1. What is a pointer?
2. What is NULL pointer?
3. What is pointer arithmetic?
4. Can we add 2 pointers? → No
5. What is void pointer?
6. Why array name is a pointer?
7. Difference between *p and p?
8. Can pointers be compared?
9. What is dangling pointer?
10. What is double pointer?
📘 C Pre-processor Directives & Macros —
1 — INTRODUCTION TO THE C PRE-PROCESSOR
1. What is a Pre-processor?
The C Pre-processor (CPP) is a program that processes source code before compilation.
It handles:
Macro expansions
Header file inclusion
Conditional compilation
File operations
Symbolic constants
Pre-processor instructions start with # and run before the compiler.
2. Stages of C Program Compilation
1. Editing – writing code
2. Pre-processing – handles # directives
3. Compilation – converts to machine code
4. Linking – connects libraries
5. Execution
Pre-processing is the first transformation stage.
3. Features of the Pre-processor
No semicolon required
Does not require memory
Operates on plain text
Increases readability & efficiency
Supports conditional compilation
4. Types of Pre-processor Directives
1. Macros (#define)
2. File Inclusion (#include)
3. Conditional Compilation (#if, #ifdef, etc.)
4. Miscellaneous directives (#undef, #pragma)
2 — MACROS IN DETAIL
1. What is a Macro?
A macro is a named piece of code that gets textually substituted before compilation.
Syntax
#define name replacement_text
Example
#define PI 3.1415
#define MAX 100
Whenever PI is used, the pre-processor replaces it with 3.1415.
2. Types of Macros
A) Object-like Macros
Behave like constants.
#define LENGTH 10
B) Function-like Macros
Act like inline functions.
#define SQUARE(x) ((x)*(x))
Important: Parentheses must be used to avoid logical errors.
Example:
SQUARE(3+2) → ((3+2)*(3+2)) = 25
C) Parameterized Macros
Take multiple arguments.
#define MAX(a,b) ((a) > (b) ? (a) : (b))
D) Multi-line Macros
Use backslash \ to extend macro to next line.
#define PRINT_VALUES(a,b) \
printf("A = %d\n", a); \
printf("B = %d\n", b);
E) Predefined Macros
C provides built-in macros:
Macro Meaning
__DATE__ Compilation date
__TIME__ Compilation time
__FILE__ Current filename
__LINE__ Current line number
__STDC__ Standard C compliance
Example:
printf("%s", __FILE__);
3 — FILE INCLUSION DIRECTIVES
1. What is File Inclusion?
Instructs the pre-processor to include external files in the program.
Syntax
#include <filename>
#include "filename"
2. Types of File Inclusion
A) System Header Files
#include <stdio.h>
#include <math.h>
Compiler searches in system directories.
B) User-defined Header Files
#include "myfile.h"
Compiler searches in current working directory first.
3. Example of User-Defined Header
myfile.h
#define CITY "Delhi"
void display();
main.c
#include "myfile.h"
Pre-processor inserts contents of the header at compile time.
4 — CONDITIONAL COMPILATION DIRECTIVES
Conditional compilation allows selective inclusion of code.
Useful for:
Debugging
OS-specific code
Large project management
Feature toggling
1. #if, #elif, #else, #endif
#if X > 10
printf("Greater");
#else
printf("Smaller");
#endif
2. #ifdef and #ifndef
Used to check if a macro is defined.
#ifdef DEBUG
printf("Debug mode");
#endif
#ifndef PI
#define PI 3.14
#endif
3. #undef — Undefine Macro
#undef MAX
4. #pragma — Special Compiler Instructions
Examples:
#pragma startup
#pragma exit
#pragma warn
Platform/compiler-specific behavior.
5. Use Cases
✔ Debug mode vs Release mode
✔ Cross-platform code
✔ Enabling/disabling features
✔ Avoiding multiple definitions
5 — ADVANTAGES OF PRE-PROCESSOR & MACROS + VIVA NOTES
1. Advantages of Pre-processor Directives
A) Increased Readability
Using symbolic names:
#define PI 3.14159
is easier than writing constant repeatedly.
B) Reduces Code Duplication
Macros allow writing reusable code blocks.
C) Faster Execution
Macro functions are expanded inline, reducing function call overhead.
D) Conditional Compilation
Allows selective inclusion/exclusion of code, improving:
portability
testing
modularity
E) Avoids Magic Numbers
Improves maintainability.
#define MAX_SIZE 100
F) Helps Multi-file Projects (Header Files)
Common declarations placed in header files prevent redundancy.
2. Disadvantages of Macros (Exam Point)
❌ No type checking (can cause errors)
❌ Hard to debug because errors appear after expansion
❌ Code size increases (inline expansion)
❌ Cannot create complex logic as easily as functions
3. Differences: Macro vs Function
Macro Function
Text replacement. Code execution
Faster (no call overhead). Slightly slower
No type checking. Type checking
Hard to debug. Easy to debug
Can cause unexpected results Safer
4. Practical Examples
Debug Mode Example
#define DEBUG
#ifdef DEBUG
printf("Running in Debug Mode\n");
#endif
OS-Specific
#ifdef _WIN32
printf("Windows");
#else
printf("Other OS");
#endif
5. Viva Questions
1. What is pre-processing?
2. Why does every directive start with #?
3. Difference between < > and " " in #include.
4. What is macro expansion?
5. Explain predefined macros.
6. Why are parentheses important in function macros?
7. What is conditional compilation?
8. What is the role of #undef?
9. How are header guards used?
10. Difference between macros and constants?
CHAPTER 4:-
📘 STORAGE CLASS SPECIFIERS IN C —
Storage classes in C define lifetime, scope, visibility, and memory location of variables.
They tell the compiler how and where a variable should be stored, and how long it should exist.
The four main storage class specifiers are:
1. auto
2. extern
3. static
4. register
Each has a specific purpose and affects the behavior of variables during program execution.
1. INTRODUCTION TO STORAGE CLASSES
A storage class in C provides information about:
1. Storage Duration
How long the variable will exist in memory:
Entire program execution?
Only during a block or function?
2. Scope
Where it can be accessed:
Local block?
Entire file?
Outside file?
3. Linkage
Can other files or functions access it?
4. Memory Location
Where the variable is stored:
RAM (normal memory)
CPU registers
Data segment
Stack
Storage classes help control the use of memory and optimize performance.
2. auto STORAGE CLASS
Definition
auto stands for automatic storage class.
It is the default storage class for local variables.
Syntax
auto int x; // explicit
int x; // implicit (same as auto)
Characteristics
Property. Description
Scope. Local to the block where variable is declared
Lifetime. Exists only during execution of that block/function
Default Value. Garbage value
Memory Location Stack
Linkage. No linkage (cannot be used outside the block)
Example
#include <stdio.h>
int main() {
auto int x = 10;
auto int x = 20;
printf("%d\n", x); // 20 (inner block)
printf("%d\n", x); // 10 (outer block)
Notes
Most C programmers do not explicitly use auto because it is default.
Useful only for educational clarity.
3. extern STORAGE CLASS
Definition
extern is used to declare a global variable defined in another file or location.
It does not allocate memory, only refers to a variable.
Purpose
To access a variable or function across multiple files.
Provides global linkage.
Syntax
extern int x; // declaration (no memory allocation)
Characteristics
Property. Description
Scope. Global (whole program)
Lifetime. Entire program execution
Default Value. 0
Memory Location Data segment
Linkage. External linkage
Simple Example
File 1: a.c
int x = 100; // definition
File 2: b.c
extern int x; // declaration
printf("%d", x);
Key Points
extern helps in modular programming.
Does not allow initialization with declaration.
extern int x = 10; // ❌ not allowed (treated as definition)
4. static STORAGE CLASS
Definition
A variable declared with static has:
Local scope (if inside a function)
Program lifetime
Preserved value between function calls
Syntax
static int x;
Characteristics
Property. Description
Scope. Depends on location: local (inside function) or file-level (global)
Lifetime. Entire program execution
Default Value. 0
Memory Location Data segment
Linkage. Internal (for global static)
A. static Inside a Function
Variable retains value across function calls.
Example
#include <stdio.h>
void counter() {
static int count = 0;
count++;
printf("%d\n", count);
int main() {
counter(); // 1
counter(); // 2
counter(); // 3
Behavior
count is created only once.
Value persists between calls.
B. static Global Variable
Makes a global variable visible only within the same file.
Provides internal linkage.
Example
static int x = 10; // accessible only in this file
Why use static global?
To prevent name conflicts in multi-file projects.
To hide internal data from other files (encapsulation).
5. register STORAGE CLASS
Definition
register suggests the compiler to store the variable in a CPU register instead of RAM for faster access.
Syntax
register int x;
Characteristics
Property. Description
Scope. Local to block
Lifetime. Until the block ends
Default Value. Garbage
Memory Location CPU registers (if available)
Linkage. No linkage
Example
register int i;
for (i = 0; i < 10000; i++) {
// fast loop
Important Points
Not guaranteed that variable will be stored in a register — compiler decides.
Cannot use & operator (address) on register variables.
register int x;
printf("%p", &x); // ❌ error
6. COMPARISON OF STORAGE CLASSES
Feature auto. extern static. register
Scope Local Global. Local/File. Local
Lifetime Block. Entire program Entire program Block
Memory Stack. Data segment. Data segment. CPU register
Default Value Garbage 0. 0. Garbage
Linkage None. External. Internal/None. None
7. WHEN TO USE WHICH STORAGE CLASS?
Use auto when:
Declaring normal local variables.
You want default behavior.
Use extern when:
You need to access global variables across files.
You want modular programming.
Use static when:
You want variable persistence across function calls.
You want to limit global variable access to a single file.
Use register when:
You need fast access to variables in loops.
The variable is used heavily in computations.
8. ADVANTAGES OF USING STORAGE CLASSES
1. Better Memory Management
Controls where and how long variables occupy memory.
2. Performance Optimization
register and static improve speed.
3. Modularity
extern helps link multiple files.
4. Data Protection
static hides variables from other files.
5. Clear Program Structure
Easy understanding of lifetime and scope.
✔️SUMMARY
Storage classes provide control over:
Scope
Lifetime
Visibility
Memory location
Each storage class serves a specific purpose:
Storage Class Use
auto. Default local variables
extern. Share variables across files
static. Persistent variables & file-level encapsulation
register. Fast-access variables
Understanding them helps write optimized, structured, and modular C programs.
📘 STRUCTURES IN C — DETAILED NOTES (5 PAGES)
Structures are one of the most powerful features in the C programming language. They allow grouping
of different types of data under a single name, making programs more organized, readable, and scalable.
Structures are widely used in real-world applications like databases, student records, inventory systems,
file handling, and operating systems.
1. INTRODUCTION TO STRUCTURES
In C programming, a structure (also called struct) is a user-defined data type that allows grouping
variables of different data types under a single unit.
Why structures?
Built-in data types (int, float) can hold only one value at a time.
Arrays can store multiple values, but only of same data type.
Real-world data consists of mixed data types (example: student record).
So, structures help represent complex data models.
2. DEFINITION OF STRUCTURES
A structure is defined using the keyword struct.
General Syntax
struct structure_name {
data_type member1;
data_type member2;
...
data_type memberN;
};
Example
struct Student {
int roll;
char name[50];
float marks;
};
This creates a new data type named struct Student.
NOTE
Structure definition ends with a semicolon.
This definition only creates a blueprint, not memory.
3. DECLARING STRUCTURE VARIABLES
Structure variables can be declared in two ways:
A) After structure definition
struct Student s1, s2;
B) Along with definition
struct Student {
int roll;
char name[20];
float marks;
} s1, s2;
Memory Allocation
Each structure variable gets its own memory for all members.
Example:
int = 4 bytes
char[20] = 20 bytes
float = 4 bytes
Total memory = 28 bytes per structure variable.
4. ACCESSING STRUCTURE MEMBERS
Use the dot operator (.).
Example
[Link] = 101;
[Link] = 89.5;
strcpy([Link], "Aarav");
To print:
printf("%d %s %f", [Link], [Link], [Link]);
5. typedef WITH STRUCTURES
The keyword typedef gives an alternate name to a data type.
Why typedef?
Shortens lengthy struct declarations.
Improves readability.
Syntax
typedef struct structure_name {
...members...
} alias_name;
Example
typedef struct Student {
int roll;
char name[20];
float marks;
} STU;
Now use:
STU s1, s2;
typedef without struct name
typedef struct {
int x;
int y;
} Point;
Point p1;
Useful when no need to use the original struct name.
6. NESTED STRUCTURES
A structure can have another structure as its member.
This allows modeling complex real-life data.
Example: Address inside Student
struct Address {
char city[20];
int pin;
};
struct Student {
int roll;
char name[20];
struct Address addr;
};
Accessing nested members
struct Student s;
[Link] = 560001;
strcpy([Link], "Delhi");
Real-life Example
struct Date {
int day, month, year;
};
struct Employee {
int id;
char name[20];
struct Date join_date; // Nested structure
};
7. ARRAY OF STRUCTURES
You can create multiple records using an array of structures.
Syntax
struct Student s[50]; // 50 students
Example
struct Student {
int roll;
char name[20];
float marks;
};
struct Student s[3];
for (int i = 0; i < 3; i++) {
scanf("%d", &s[i].roll);
scanf("%s", s[i].name);
scanf("%f", &s[i].marks);
Access
printf("Roll: %d", s[1].roll);
printf("Name: %s", s[2].name);
8. STRUCTURE ASSIGNMENT
C allows assigning one structure variable to another of same type.
Example
struct Student s1 = {101, "Riya", 89.5};
struct Student s2;
s2 = s1; // allowed
Important Points
Assignment copies all members at once.
Member-by-member copy is not needed.
Both structures must be of the same structure type.
9. STRUCTURE INITIALIZATION
Example
struct Car {
char brand[20];
int price;
};
struct Car c1 = {"Toyota", 900000};
For partial initialization:
struct Car c2 = {.price = 500000};
10. STRUCT PADDING & ALIGNMENT (THEORY)
Compilers often insert extra bytes (padding) between structure members for faster memory access.
Example
struct A {
char a; // 1 byte + 3 bytes padding
int b; // 4 bytes
};
Total memory = 8 bytes (not 5).
This is important in interviews and memory-related programming.
11. Structures vs Arrays vs Unions
Structures
Can store different data types.
Consume more memory.
Mostly used for complex data.
Arrays
Store same data type.
Suitable for bulk data of identical type.
Unions
Share memory among members.
Only one member holds a meaningful value at a time.
12. APPLICATIONS OF STRUCTURES
Structures are used almost everywhere in system-level and application programming.
✔ Student database systems
✔ Employee management
✔ Inventory & billing systems
✔ File handling (struct stat)
✔ Socket programming (struct sockaddr)
✔ Operating systems (process control blocks)
✔ Linked lists, trees, graphs (DSA)
13. PRACTICE PROGRAMS
Program 1: Nested structure example
#include <stdio.h>
struct Address {
char city[20];
int pin;
};
struct Student {
int roll;
char name[20];
struct Address addr;
};
int main() {
struct Student s = {1, "Aman", {"Delhi", 110001}};
printf("%s %d\n", [Link], [Link]);
Program 2: Array of structures
struct Employee {
int id;
char name[20];
float salary;
};
int main() {
struct Employee e[3];
for (int i = 0; i < 3; i++) {
scanf("%d %s %f", &e[i].id, e[i].name, &e[i].salary);
Topic. Key Points
Structure. User-defined data type with mixed members
typedef. Creates short alias names
Nested Structure. A structure inside another structure
Array of Structure. Multiple records stored together
Structure Assignment Entire structure can be copied directly
Structures support complex data, modularity, real-life data representation, and memory management.
📘 STRUCTURES AS ARGUMENTS & RETURN VALUES; POINTERS TO STRUCTURES
Structures in C are extremely powerful for representing real-life data models. Using them with functions
and pointers helps build large programs like databases, games, compilers, record systems, etc.
This chapter covers:
1. Structures as function arguments
2. Call-by-value vs call-by-reference using structures
3. Returning structures from functions
4. Pointers to structures
5. Arrow operator (→)
6. Dynamic structures with malloc
7. Best practices
1. STRUCTURES AS FUNCTION ARGUMENTS
Just like integers and floats, entire structures can be passed to functions. This feature allows passing a
group of data items as a single unit.
Two ways to pass structures to functions
1. Pass by value
2. Pass by reference (using pointers)
1.1 Pass Structure by Value
When a structure is passed by value, a copy of the structure is supplied to the function.
Syntax
void display(struct Student s);
Example
struct Student {
int roll;
float marks;
};
void show(struct Student s) {
printf("%d %.2f", [Link], [Link]);
int main() {
struct Student stu = {101, 89.5};
show(stu); // copy passed
Important Characteristics
Changes made inside function do not affect the original structure.
Safe, but slightly slower for large structures.
Best for read-only operations.
1.2 Call-by-Value: Advantages & Disadvantages
Advantages
Original data remains safe.
Good when modifications are not required.
Disadvantages
Copying large structures consumes time + memory.
Not efficient for large programs.
2. PASS STRUCTURES BY REFERENCE (Using Pointer)
Passing by reference means sending the address of the structure to the function.
Syntax
void update(struct Student *s);
Example
void update(struct Student *s) {
s->marks = s->marks + 10;
int main() {
struct Student stu = {101, 70};
update(&stu);
printf("%f", [Link]); // prints 80
Characteristics
No copy is created — more efficient.
Changes reflect in the original structure.
Used for modifying structure data.
3. COMPARISON: PASS BY VALUE VS PASS BY POINTER
Feature. Pass by Value. Pass by Pointer
Memory. More (copies structure) Less
Speed. Slower. Faster
Safety. Safe. Risky if incorrectly used
Effect on original No change. Changes reflect
Best use. Read-only operations. Modifications, large data
4. RETURNING STRUCTURES FROM FUNCTIONS
C allows returning a whole structure from a function.
This is extremely useful in:
Creating functions like getStudent(), createDate()
Implementing ADTs (Abstract Data Types)
Data processing tasks
4.1 Syntax
struct Student input() {
struct Student s;
scanf("%d %f", &[Link], &[Link]);
return s;
4.2 Example
struct Point {
int x, y;
};
struct Point createPoint(int a, int b) {
struct Point p;
p.x = a;
p.y = b;
return p;
int main() {
struct Point p1 = createPoint(10, 20);
printf("%d %d", p1.x, p1.y);
Key Notes
Entire structure is returned.
Caller receives a copy of the returned structure.
Very useful in data abstraction.
5. RETURN STRUCTURE USING POINTERS (Alternative Method)
Instead of returning a structure by value, we can return a pointer to a structure.
Example
struct Student* create() {
struct Student *s = malloc(sizeof(struct Student));
s->roll = 1;
s->marks = 90;
return s;
Important
Must use malloc for dynamically allocated structures.
Data persists until free() is used.
6. POINTERS TO STRUCTURES
Pointers to structures make it possible to:
Modify structure inside functions
Access dynamic structures
Create linked lists, trees, graphs (DSA)
6.1 Syntax
struct Student *ptr;
Assigning Address
ptr = &s1;
*Access using (ptr).member
(*ptr).roll = 101;
7. ARROW OPERATOR (→)
Since (*ptr).member is used frequently, C provides:
ptr->member
Example
ptr->roll = 101;
ptr->marks = 89.5;
7.1 Example Program Using Arrow Operator
struct Book {
char title[30];
float price;
};
int main() {
struct Book b = {"C Programming", 550};
struct Book *p = &b;
printf("%s %.2f", p->title, p->price);
8. ARRAY OF STRUCTURE POINTERS
Useful in dynamic databases.
Example
struct Employee {
int id;
float salary;
};
struct Employee *e[5]; // array of pointers
9. POINTERS WITH NESTED STRUCTURES
Example
struct Address {
char city[20];
int pin;
};
struct Student {
int roll;
struct Address addr;
};
struct Student s, *p;
p = &s;
p->[Link] = 110001;
10. DYNAMIC MEMORY ALLOCATION WITH STRUCTURES
Dynamic structures allow creation at runtime.
Example
struct Node {
int data;
struct Node *next;
};
struct Node *temp = malloc(sizeof(struct Node));
temp->data = 10;
temp->next = NULL;
Used in linked lists, stacks, queues, trees, graphs.
11. STRUCTURE ASSIGNMENT USING POINTERS
struct Student s1, s2;
s1 = s2; // valid
struct Student *p1 = &s1;
struct Student *p2 = &s2;
*p1 = *p2; // assign through pointers
12. IMPORTANT RULES
✔ You can pass structure by value
✔ You can pass structure pointer
✔ You can return a structure by value
✔ You can return pointer to a dynamically created structure
✖ You cannot return pointer to a local structure (goes out of scope)
13. PRACTICE PROGRAMS (HIGH EXAM VALUE)
Program 1: Pass Structure by Value
struct Student {
int roll;
float marks;
};
void print(struct Student s) {
printf("%d %.2f", [Link], [Link]);
Program 2: Pass Structure by Pointer
void update(struct Student *s) {
s->marks += 5;
Program 3: Return Structure
struct Student get() {
struct Student s = {101, 90.5};
return s;
Program 4: Pointer to Structure + arrow
struct Rectangle {
int l, b;
};
int area(struct Rectangle *r) {
return r->l * r->b;
Concept. Description
Structure by Value. Copy passed; original unchanged
Structure by Pointer. Address passed; original modified
Returning Structure. Whole structure returned by value
Returning Pointer to Structure Efficient; often used with malloc
Pointer to Structure. Used with → operator
Dynamic Structure. Created using malloc for DS/Memory-intensive tasks
Structures can be passed to and returned from functions.
Passing by value → safe, slower
Passing by pointer → fast, allows modification
Arrow operator (→) is used for structure pointers
Structures + pointers = foundation of linked lists, trees, graphs
Dynamic structures allow creation of nodes at runtime
📘 UNIONS & MEMORY LAYOUT —
Unions in C are an important user-defined data type similar to structures, but with one major difference:
all members share the same memory location. This makes unions memory-efficient but more restrictive
than structures. Understanding unions is essential for interviews, embedded systems, compilers, and
data-compression applications.
1. INTRODUCTION TO UNIONS
A union is a user-defined data type where all members occupy the same memory, and only one member
can contain a meaningful value at a time.
Syntax
union union_name {
data_type member1;
data_type member2;
...
};
Example
union Data {
int i;
float f;
char str[20];
};
Key Difference from Structure
Structure: each member has separate memory.
Union: all members share the same memory block.
This makes unions memory-efficient.
2. DECLARING UNION VARIABLES
Syntax
union Data d1, d2;
With definition
union Data {
int i;
float f;
char str[20];
} d1, d2;
3. ACCESSING UNION MEMBERS
Use the dot operator like structures.
d1.i = 10;
d1.f = 20.5; // overwrites previous value
Important
Assigning a value to one member overwrites the value of other members because memory is shared.
4. MEMORY SIZE OF UNIONS
The size of a union is equal to the size of its largest member, not the sum of all members.
Example
union Data {
int i; // 4 bytes
float f; // 4 bytes
char str[20]; // 20 bytes
};
Memory allocated = 20 bytes (size of largest member str)
Reason
All members start from the same memory address.
5. HOW UNION MEMORY WORKS (Memory Layout)
Unions store all members at offset 0 (same address).
Example:
union Test {
int x;
char y;
float z;
};
Memory Layout Diagram
Bytes: 0 1 2 3
----------------
| x/y/z shared |
----------------
All members overlap.
Writing to one member overwrites others.
6. ILLUSTRATION WITH DIAGRAM
Assume:
union U {
int a; // 4 bytes
char b[4]; // 4 bytes
};
Same memory used:
Address →
+----+----+----+----+
| a | a | a | a | ← union.a
+----+----+----+----+
| b[0] b[1] b[2] b[3] | ← union.b[]
+---------------------+
Whatever you write using b[] affects a, and vice versa.
7. USING UNIONS: PRACTICAL EXAMPLES
Example 1: Storing different data at different times
union Value {
int i;
float f;
char c;
};
union Value v;
v.i = 10; // valid
v.f = 3.14; // overwrites v.i
v.c = 'A'; // overwrites v.f
Only the last assigned member holds meaningful data.
8. UNIONS WITH STRUCTURES
You can embed unions inside structures or vice versa.
Example
struct Student {
int type;
union {
int roll;
float gpa;
} data;
};
Used in:
Tokenizers
Parsers
Sensor reading where only one value is needed at a time
9. DIFFERENCE: STRUCTURES vs UNIONS
Feature Structure. Union
Memory Sum of all members. Max size of any member
Members All exist simultaneously. Only one valid at a time
Usage. Complex records. Memory-critical operations
Storage Different memory for each member Shared memory
10. USE CASES OF UNIONS
A. Memory Saving (Embedded Systems)
Microcontrollers have very low memory (Flash/RAM).
Union helps store multiple data types in the same byte(s).
B. Interpreting Same Memory as Different Types
Used in:
Type punning
Low-level memory management
Communication protocols
C. Variant Data Types
Example: Data packets where the type varies:
struct Packet {
int type;
union {
int intValue;
float floatValue;
char str[30];
} data;
};
D. Efficient Storage
Perfect for:
Sensors
Data decoding
Hardware registers
11. UNION WITH POINTERS (Advanced)
Pointers to unions are similar to pointers to structures.
Syntax
union Data *p;
Accessing members
p->i = 10;
12. MEMORY LAYOUT: STRUCTURE VS UNION
Structure
+----------+----------+----------+
| int | float | char[] |
+----------+----------+----------+
Total size = sum
Union
+--------------------------------+
| largest member (shared memory) |
+--------------------------------+
Total size = max
13. REAL MEMORY EXAMPLE (With Sizes)
union example {
int a; // 4 bytes
double b; // 8 bytes
char c[3]; // 3 bytes
};
Memory allocated = 8 bytes (size of double)
14. COMMON MISTAKES WITH UNIONS
❌ Using multiple members at once
❌ Expecting structure-like behavior
❌ Forgetting only last written value is valid
❌ Assuming union initializes all members at once
❌ Type confusion due to overlapping bytes
15. APPLICATIONS IN REAL PROGRAMS
✔ Device drivers
✔ Operating systems (hardware registers)
✔ Low-level data access
✔ Interpreting binary data
✔ Networks and protocol implementation
✔ Compilers & interpreters (token unions)
✔ Embedded C systems
16. EXAMPLE PROGRAMS (High Exam Value)
Program 1: Basic Union
union Test {
int x;
float y;
};
int main() {
union Test t;
t.x = 10;
printf("%d", t.x);
t.y = 5.5;
printf("%f", t.y);
Program 2: Union Memory Demonstration
union U {
int a;
char b[4];
};
int main() {
union U u;
u.a = 16909060; // 0x01020304
printf("%d %d %d %d", u.b[0], u.b[1], u.b[2], u.b[3]);
Program 3: Union in Structure
struct Packet {
int type;
union {
int i;
float f;
} data;
};
17. ADVANTAGES OF UNIONS
✔ Memory Efficient
✔ Useful for Variant Data
✔ Faster (less memory to move)
✔ Ideal for Embedded Systems
✔ Used for Multi-type Interpretation
18. LIMITATIONS OF UNIONS
✖ Only one member is valid at a time
✖ Hard to debug
✖ Not suitable for large mixed data
✖ Requires careful handling
19. EXAM-READY SUMMARY
Union stores different data types in the same memory location.
Size = size of largest member.
Only last assigned value is preserved.
Access using dot operator.
Useful in memory-critical systems and type conversions.
Structures store all members separately; unions share memory.
Unions inside structures support flexible data representation.
C++ Introduction: Classes & Objects; Pointers within Structures
1. Introduction to C++ as an Object-Oriented Programming Language
C++ (developed by Bjarne Stroustrup at Bell Labs) is an extension of C that adds Object-Oriented
Programming (OOP) features.
It supports both:
Procedural programming (like C)
Object-oriented programming
This is known as multi-paradigm or hybrid programming.
Major OOP Features in C++
1. Classes & Objects
2. Encapsulation (data hiding)
3. Abstraction
4. Inheritance
5. Polymorphism
6. Dynamic Binding
7. Message Passing
Need for OOP
Procedural programming focuses on functions, but OOP focuses on data.
OOP solves issues like:
Code complexity
Data scattering
Reusability
Security
Large-scale software maintenance
C++ introduces the concept of classes and objects, which form the foundation of OOP.
2. Introduction to Classes in C++
2.1 What is a Class?
A class is a user-defined data type that groups data and functions under a single unit.
It represents a blueprint or template.
Example analogy:
Class = Blueprint of a house
Object = Actual house built from the blueprint
Definition
class ClassName {
private:
// data members
public:
// member functions
};
Components of a Class
1. Data Members → variables inside class.
2. Member Functions → functions operating on data members.
3. Access Specifiers:
private (default) → accessible only inside class
public → accessible anywhere
protected → accessible in derived classes
Example of Class
class Student {
private:
int roll;
float marks;
public:
void input() {
cin >> roll >> marks;
}
void display() {
cout << roll << " " << marks;
};
3. Introduction to Objects
3.1 What is an Object?
An object is an instance of a class.
When a class is defined, no memory is allocated.
Memory is allocated only when objects are created.
Declaration of Objects
Student s1; // object creation
Student s2;
Accessing Class Members
Use dot operator (.):
[Link]();
[Link]();
4. Constructors and Destructors (Brief Overview)
Although not required, understanding them helps build strong fundamentals.
Constructor
Special member function
Same name as class
Automatically called when object is created
Used to initialize objects
Example:
Student() {
roll = 0;
marks = 0;
Destructor
Name: ~ClassName()
Automatically called when object goes out of scope
Used for cleanup tasks
Example:
~Student() {
cout << "Object destroyed";
5. Memory Allocation for Objects
Each object gets its own copy of:
Data members
But member functions belong to class, not individual objects.
Thus:
Student s1, s2;
s1 and s2 have separate roll numbers and marks.
6. Pointers in C++ (Foundation for Pointer-to-Structure Concepts)
Pointers store memory addresses.
Example
int a = 10;
int *p = &a;
7. Structures & Pointers (C++ Support)
Although classes are preferred, structures are still used in C++ for:
Lightweight data grouping
C compatibility
Linked lists, trees, graphs
7.1 Structure Definition
struct Person {
int age;
float weight;
};
7.2 Creating Structure Variables
Person p1;
8. Pointers to Structures
A structure pointer stores address of a structure variable.
Example
Person p1;
Person *ptr = &p1;
Accessing Members via Pointer
Use the arrow operator ( → ):
ptr->age = 25;
ptr->weight = 67.5;
-> is equivalent to:
(*ptr).age
9. Dynamic Memory Allocation for Structures in C++
Unlike classes, structures also support dynamic memory allocation using new and delete.
Example
Person *p = new Person;
p->age = 20;
p->weight = 55.5;
delete p;
Array of Structures (Dynamic)
Person *arr = new Person[5];
arr[0].age = 18;
delete[] arr;
10. Structures Inside Classes (Composition)
Often a class contains structures.
Example:
struct Address {
int houseNo;
string city;
};
class Employee {
private:
Address addr;
public:
void set() {
[Link] = 50;
[Link] = "Delhi";
};
This is called object composition.
11. Using Pointers Within Structures
A structure can itself contain pointers.
This is useful for:
Linked lists
Trees
Dynamic strings
Graphs
11.1 Example: Structure Containing Pointer
struct Node {
int data;
Node *next;
};
This is the fundamental building block of a linked list.
Explanation
data stores value
next stores address of another Node
Allows dynamic chain of nodes
Creating Node Dynamically:
Node *n1 = new Node;
n1->data = 10;
n1->next = nullptr;
12. Self-Referential Structures
A structure that contains a pointer to its own type is called a self-referential structure.
Example:
struct Employee {
int id;
Employee *manager;
};
Use-cases:
Trees
Linked lists
Hierarchy systems
13. Structures with Pointer Data Members
Structures can contain pointers to:
int
float
char
Arrays
Strings
Dynamically allocated memory
Example: Dynamic String in Structure
struct Student {
char *name;
int age;
};
Allocating memory
Student s;
[Link] = new char[20];
strcpy([Link], "Rahul");
Freeing memory
delete[] [Link];
14. Classes vs. Structures in C++ (Important 5-Mark Question)
Feature. Class. Structure
Default access private. public
OOP support. Full. Limited
Functions inside Yes. Yes
Inheritance. Allowed. Not allowed for structs
Constructors. Yes. Yes
Usage Large programs Lightweight grouping
15. Combining Classes and Structure Pointers
Example Program
struct Date {
int d, m, y;
};
class Employee {
private:
Date *DOJ;
public:
Employee(int dd, int mm, int yy) {
DOJ = new Date;
DOJ->d = dd;
DOJ->m = mm;
DOJ->y = yy;
void show() {
cout << DOJ->d << "/" << DOJ->m << "/" << DOJ->y;
~Employee() {
delete DOJ;
};
Key Concepts Demonstrated:
Class containing pointer to structure
Dynamic structure allocation
Memory cleanup in destructor
16. Advantages of Using Classes, Objects & Pointers in Structures
Advantages of Classes & Objects
Modularity
Code reusability
Data hiding (security)
Easy maintenance
Better organization for large programs
Advantages of Pointers within Structures
Efficient memory usage
Create dynamic data structures
Easy implementation of complex systems
Supports chaining and hierarchical models
A class is a user-defined data type containing data & functions.
An object is an instance of class; memory is allocated when object is created.
Structures can store pointers, including self-referential pointers.
-> operator is used to access structure or class members through pointers.
Structures can be created dynamically using new.
Class can contain structure pointers, and structures can contain pointers to class objects.
Pointers inside structures enable creation of linked lists, trees, graphs, and dynamic data systems.
CHAPTER 5:-
Constructors & Destructors in C++
1. Introduction to Constructors and Destructors
In Object-Oriented Programming (OOP), constructors and destructors are special member functions that
control the lifecycle of an object.
Every time an object is created, a constructor is executed automatically.
Every time an object is destroyed, a destructor is executed automatically.
They help in:
Initializing objects
Allocating resources
Releasing resources
Ensuring smooth object lifecycle
2. Constructor: Definition
A constructor is a special member function of a class that:
Has the same name as the class
Has no return type (not even void)
Is automatically invoked when an object is created
Is used to initialize data members of the class
General Syntax
class ClassName {
public:
ClassName() {
// constructor body
};
Characteristics of Constructors
1. No return type
2. Automatically executed
3. Can be overloaded
4. Cannot be inherited
5. Can be defined inside or outside the class
6. Allocates initial values to data members
3. Types of Constructors
C++ supports three main types:
1. Default Constructor
2. Parameterized Constructor
3. Copy Constructor
(Also: dynamic constructors, explicit constructors — but the above three are core syllabus topics.)
4. Default Constructor
Definition
A constructor with:
No parameters
No arguments
It initializes objects with default values.
Example
class Student {
int roll;
public:
Student() { // default constructor
roll = 0;
};
Key Points
Automatically provided by compiler if no constructor is defined.
If you define any constructor (parameterised, etc.), compiler does NOT create a default constructor
automatically.
Often used to set basic initial values.
5. Parameterised Constructor
Definition
A constructor that accepts one or more parameters.
It is used to initialize objects with user-defined values.
Syntax
class Student {
int roll;
public:
Student(int r) { // parameterised constructor
roll = r;
};
Usage
Student s1(10);
Student s2 = Student(20);
Advantages
Flexible initialization
Different objects can have different initial values
Constructor Overloading
You can create multiple constructors with different parameter lists.
Example:
Student() {}
Student(int a) {}
Student(int a, int b) {}
6. Copy Constructor
Definition
A constructor that initializes an object using another object of the same class.
General form
ClassName(const ClassName &obj);
The parameter must be passed by reference, not by value, because passing by value would call the copy
constructor again → infinite recursion.
Example
class Student {
int roll;
public:
Student(int r) { roll = r; }
Student(const Student &s) { // copy constructor
roll = [Link];
};
Usage
Student s1(10);
Student s2(s1); // copy constructor called
When Is Copy Constructor Used Automatically?
Compiler will call it:
1. When an object is initialised from another object.
2. When an object is passed by value to a function.
3. When an object is returned by value from a function.
4. During temporary object creation.
7. Shallow Copy vs Deep Copy (Important Question)
7.1 Shallow Copy
Copies only data values.
Does not create new memory for pointer members.
Pointer members point to same memory location.
Dangerous when using delete.
Example of shallow copy
Object A -----> [value at memory X]
Object B -----> [SAME memory X]
7.2 Deep Copy
Copies values + allocates new memory for pointer members.
Both objects have independent copies.
Example
Object A -----> [memory X]
Object B -----> [NEW memory Y]
A good copy constructor must implement deep copy when class contains pointers.
8. Destructor Definition
A destructor is a special member function that:
Has the same name as the class but preceded by ~ (tilde)
Has no parameters
Has no return type
Is automatically invoked when the object goes out of scope
General syntax
~ClassName() {
// cleanup code
Purpose
Free dynamically allocated memory (new)
Close files
Release resources (database connections, handles, etc.)
Example
class Demo {
public:
~Demo() {
cout << "Destructor called";
};
When Destructor Is Called?
1. Object goes out of scope
2. Program ends
3. delete is used for dynamic objects
4. When block ends
9. Constructor–Destructor Execution Order
Global objects
Constructors → executed before main()
Destructors → executed after main() ends
Local objects
Constructors → at entry of block
Destructors → at exit of block
For multiple objects
Constructors execute in the sequence of creation
Destructors execute in reverse order
Example:
A a1;
A a2;
Order:
Construct a1
Construct a2
Destruct a2
Destruct a1
10. Dynamic Constructor
It allocates memory dynamically using new.
Example:
class Demo {
int *p;
public:
Demo() {
p = new int; // dynamic allocation
}
~Demo() {
delete p; // deallocation
};
11. Constructor Outside Class Definition
Constructors can be defined outside the class using scope resolution operator ::.
Example:
class Test {
public:
Test();
};
Test::Test() {
cout << "Constructor outside class";
12. Explicit Keyword (Important)
Prevents implicit conversion through constructors.
Example:
explicit Test(int x);
Prevents:
Test t = 5; // ERROR
13. DEFAULT vs PARAMETERISED vs COPY: Comparison
Feature. Default Parameterised. Copy
Parameters. No. Yes. One (reference)
Use. Basic initialization User-defined initialization Copy object
Called. Automatically. When arguments exist When object copied
Created by compiler? Yes (if none defined) No. Yes (compiler-
provided shallow copy)
14. Compiler-Generated Constructors
If no constructors are defined, compiler provides:
Default constructor
Copy constructor
Default assignment operator
But when you define one constructor, compiler only supplies remaining if needed.
15. Practical Example: All Types of Constructors
class Student {
int roll;
public:
Student() { // default
roll = 0;
Student(int r) { // parameterised
roll = r;
Student(const Student &s) { // copy
roll = [Link];
~Student() { // destructor
cout << "Object destroyed";
}
};
16. Lifecycle Example (Important for Viva)
Student s1; // default
Student s2(10); // parameterised
Student s3(s2); // copy
} // end of scope → destructors called 3 times
17. Most Important Theoretical Questions (Exam Points)
1. Define constructor.
2. List types of constructors.
3. Define default constructor with example.
4. Define parameterised constructor with example.
5. What is the need for a copy constructor?
6. Explain shallow copy vs deep copy.
7. Define destructor with example.
8. Why copy constructor must accept reference?
9. Why destructor has no parameters?
10. Explain order of constructor and destructor calls.
A constructor initializes an object; a destructor destroys it.
Default constructor → no arguments.
Parameterised constructor → arguments allowed.
Copy constructor → initializes object from another object.
Destructor name = ~ClassName() with no arguments.
Constructors can be overloaded; destructors cannot.
Deep copying prevents pointer-related errors.
Constructors execute in creation order; destructors in reverse.
C++ Notes: Arrays of Objects & Objects as Arguments
1. INTRODUCTION
In Object-Oriented Programming (OOP), objects are the fundamental building blocks. In C++, not only
can we create individual objects, but we can also create collections of objects and pass objects to
functions for processing.
This topic primarily covers:
Array of objects
Passing objects to functions
Returning objects from functions
Call-by-value vs call-by-reference for objects
Use-cases and memory behavior
Understanding these concepts is essential for implementing real-world applications such as managing
student records, employee databases, inventory systems, and more.
2. ARRAYS OF OBJECTS
2.1 What is an Array of Objects?
An array of objects is a group of object variables stored in contiguous memory locations.
Just like an array of int or float, we can create arrays where each element is an object of a class.
Syntax
class ClassName {
// data members
// member functions
};
ClassName objArray[size]; // array of objects
Example
class Student {
int roll;
float marks;
public:
void getData() {
cin >> roll >> marks;
void showData() {
cout << roll << " " << marks << endl;
};
int main() {
Student s[3]; // array of 3 Student objects
for(int i=0; i<3; i++)
s[i].getData();
for(int i=0; i<3; i++)
s[i].showData();
2.2 Memory Layout of Array of Objects
Each element of the array represents one complete object.
Objects are stored in contiguous memory, much like primitive data types.
Memory required =
size_of_object × number_of_objects
Diagram (Conceptual)
-------------------------------
| obj[0] | obj[1] | obj[2] | ...
-------------------------------
Each object contains all its data members and shares function code.
2.3 Initializing Arrays of Objects
(a) Using Loop
for(int i=0; i<n; i++)
obj[i].setData();
(b) Using Constructors
If the class has a constructor, it is invoked automatically for every object.
class A {
public:
A() { cout << "Constructor called\n"; }
};
A arr[3]; // constructor called 3 times
(c) Using Initializer List
class Demo {
int x;
public:
Demo(int a) { x = a; }
};
Demo d[3] = { Demo(1), Demo(2), Demo(3) };
3. OBJECTS AS FUNCTION ARGUMENTS
Objects, just like variables, can be passed to functions in different ways. This increases modularity and
allows operations on objects from outside the class.
3.1 Pass Object by Value
A copy of the object is sent to the function.
Changes made inside the function do not affect the original object.
Example
void display(Student s) { // pass by value
[Link](); // works on a copy
Advantages
Simple and safe (original object remains unchanged)
Disadvantages
Time-consuming for large objects (copy overhead)
Extra memory consumption
3.2 Pass Object by Reference
Function receives the actual object, not a copy.
Changes made inside reflect in the original.
Syntax
void update(Student &s); // reference parameter
Example
void update(Student &s) {
[Link] += 5;
Advantages
Fast (no copying)
Memory efficient
Disadvantages
Unintentional modification of original object
3.3 Pass Object by Pointer
Function receives the address of the object.
Access members with ->.
void modify(Student *s) {
s->marks = 100;
4. RETURNING OBJECTS FROM FUNCTIONS
C++ allows a function to return an object just like returning int/float.
Syntax
ClassName functionName() {
ClassName temp;
// assign values
return temp;
Example
Student createStudent() {
Student s;
[Link]();
return s;
Uses
Factory methods
Operations involving object combination
Returning results (e.g., a new complex number object)
5. ARRAY OF OBJECTS WITH FUNCTIONS
Case 1: Passing entire array to a function
void input(Student s[], int n) {
for(int i=0; i<n; i++)
s[i].getData();
Case 2: Passing a specific object
void show(Student s) {
[Link]();
6. REAL-WORLD USE CASES
1. Employee Database
Store 100 employee objects in an array and process them using functions.
2. Library Management
Book records in array; functions to search/update.
3. Student Marks System
Array of Student objects; functions for:
calculating average
highest scorer
result generation
4. Banking System
Multiple accounts stored in an object array; operations applied via functions.
7. DIFFERENCE TABLE
Feature. Array of Objects. Objects as
Arguments
Definition. Multiple objects stored in contiguous memory Passing object to
function
Memory. Allocated for all objects at once. Depends on pass-by-
value or reference
Usage. Record collections. Operations and
processing
Constructor Use Called for each element. Parameterized
constructors help
initialize
8. IMPORTANT EXAM PROGRAMS
Program 1: Array of Objects
class Employee {
int id;
float salary;
public:
void get() {
cin >> id >> salary;
void show() {
cout << id << " " << salary << endl;
};
int main() {
Employee e[3];
for(int i=0; i<3; i++) e[i].get();
for(int i=0; i<3; i++) e[i].show();
}
Program 2: Object as Function Argument
class Number {
int x;
public:
Number(int a) { x = a; }
void show() { cout << "x = " << x; }
};
void display(Number n) {
[Link]();
int main() {
Number obj(10);
display(obj);
Program 3: Returning Object
class Box {
int l, b;
public:
Box(int x, int y) { l = x; b = y; }
void show() { cout << l << " " << b; }
};
Box create() {
return Box(5, 10);
}
int main() {
Box b = create();
[Link]();
Arrays of objects store multiple objects in continuous memory.
Constructors run automatically for each element in an object array.
Objects can be passed by value, by reference, or by pointer.
Pass-by-reference is efficient and commonly used.
Objects can be returned from functions.
Functions help modularize operations on object arrays.
Widely used in real-life systems involving records.
C++ NOTES: REFERENCE VARIABLES & DEFAULT PARAMETERS
1. INTRODUCTION
Functions in C++ become powerful when combined with two important features:
1. Reference Variables – allow aliasing of variables.
2. Default Parameters – allow functions to have optional arguments.
Both features reduce redundancy, increase flexibility, and improve performance. These concepts are
widely used in competitive programming, real-life applications, and large-scale software development.
2. REFERENCE VARIABLES
2.1 Definition
A reference variable is an alias or an alternative name** for an existing variable.
Once a reference is initialized to a variable, it cannot refer to any other variable.
Syntax
int a = 10;
int &ref = a; // ref becomes second name for a
Now both a and ref refer to the same memory location.
2.2 Characteristics of Reference Variables
Must be initialized at the time of declaration.
Cannot be NULL.
Cannot be changed to reference another variable.
No separate memory is allocated (shares the same memory as the original variable).
Mostly used for function arguments and operator overloading.
2.3 Memory Diagram
a → [10]
ref → [10]
Both variables point to the same memory location, not copies.
2.4 Example Program
#include <iostream>
using namespace std;
int main() {
int x = 50;
int &y = x;
cout << x << " " << y << endl; // 50 50
y = 100;
cout << x << " " << y << endl; // 100 100
Output shows both x and y change simultaneously since they refer to the same location.
2.5 Uses of Reference Variables
1. Pass-by-reference in functions
Used to modify original values.
void swap(int &a, int &b) {
int temp = a;
a = b;
b = temp;
2. Operator overloading
Reference returns avoid unnecessary copies.
3. Efficient memory usage
No large object copies.
4. Returning references
Enables chain operations.
2.6 Advantages of Reference Variables
No copying overhead.
Faster execution.
Easy-to-read syntax (compared to pointers).
Safe: cannot be NULL.
Useful in function arguments and returning objects.
2.7 Disadvantages of Reference Variables
Must be initialized immediately.
Cannot be reseated (cannot refer to another variable later).
Too much aliasing may reduce code readability.
3. REFERENCES VS POINTERS (Important Question)
Feature Reference. Pointer
Null. Cannot be NULLCan be NULL
Reseating Cannot change reference Pointer can change target
Syntax a simpler alias requires * and &
Initialization Mandatory. Optional
Memory No extra memory Extra memory for pointer variable
Use-case Function arguments Dynamic memory, arrays
This table is frequently asked in viva & written exams.
4. FUNCTION ARGUMENTS USING REFERENCES
4.1 Pass-by-Reference Using Reference Variables
void increment(int &x) {
x++;
Calling:
int a = 10;
increment(a); // a becomes 11
Effect: Actual variable is modified.
4.2 Pass-by-Reference vs Pass-by-Value
Pass-by-Value. Pass-by-Reference
Copy created. No copy created
Slow for large objects. Fast
Original unchanged. Original changed
Memory overhead. No overhead
5. RETURNING REFERENCES FROM FUNCTIONS
Possible if we return reference to a static or global variable.
Example
int& fun() {
static int x = 10;
return x;
}
int main() {
int &ref = fun();
ref = 50;
cout << fun(); // 50
6. DEFAULT PARAMETERS
6.1 Definition
A default parameter is a value assigned to a function parameter which is used when the caller does not
pass any value for that parameter.
Syntax
int sum(int a, int b = 10);
If b is not provided during function call, 10 will be used.
6.2 Example Program
#include <iostream>
using namespace std;
void message(string name = "Student") {
cout << "Hello, " << name << endl;
int main() {
message(); // Hello, Student
message("Rahul"); // Hello, Rahul
7. RULES FOR DEFAULT PARAMETERS (VERY IMPORTANT)
Rule 1: Default arguments must be on the right-most side
Correct:
int display(int a, int b = 5, int c = 10);
Incorrect:
int display(int a = 10, int b); // ERROR
Rule 2: Defaults are assigned only once—in the function declaration
int fun(int a, int b = 20); // Correct
int fun(int a, int b) { ... } // No defaults here
Rule 3: Values are substituted from right to left
During function call, missing parameters get default values.
7.1 Advantages of Default Parameters
Reduces the number of overloaded functions.
Simplifies function calls.
Makes the code cleaner and more flexible.
Saves time during function invocation.
7.2 Disadvantages
Too many defaults may confuse beginner programmers.
Incorrect placement leads to syntax errors.
Not supported by all languages (but fully supported in C++).
8. DEFAULT PARAMETERS VS FUNCTION OVERLOADING
Feature. Default Parameters Function Overloading
Purpose. Optional arguments Multiple functions
Code size. Smaller. Bigger
Flexibility. Medium. High
Syntax complexity Low. Moderate
Performance. Efficient. May involve overload resolution
9. COMBINED EXAMPLE (Reference + Default)
Program
class Test {
public:
void update(int &x, int inc = 5) {
x += inc;
};
int main() {
Test t;
int a = 10;
[Link](a); // inc=5 (default)
[Link](a, 20); // inc=20
cout << a; // Output: 35
This program demonstrates:
Reference variable (x)
Default parameter (inc)
Modification of actual variable
10. REAL-LIFE USES
1. Mathematics functions
power(x, y=2) → default exponent
2. Banking systems
Interest rate as default parameter.
3. Game development
Default player speed or difficulty.
4. Sorting algorithms
Pass array by reference, use default order (ascending).
5. Machine Learning / AI Libraries
Default learning rate, epochs, batch size.
11. VIVA & THEORY QUESTIONS
1. What is a reference variable?
2. Difference between pointer and reference.
3. Why must a reference be initialized?
4. What is a default parameter?
5. Where should default parameters be declared?
6. Can default and non-default parameters be mixed?
7. Can references return from functions? Under which conditions?
Reference variables are alternate names for variables and share the same memory.
References are used for pass-by-reference, returning objects, and operator overloading.
Default parameters allow optional arguments in function calls.
Default arguments must be to the rightmost parameters.
Both concepts improve coding efficiency, simplicity, and performance.
Below are full, detailed, high-quality notes on Core OOP Pillars: Encapsulation, Inheritance &
Polymorphism—expanded to fill 5 full notebook pages, perfect for 10/10 CGPA college submission and
exams.
Core OOP Pillars: Encapsulation, Inheritance & Polymorphism**
1. INTRODUCTION TO OOP PILLARS
Object-Oriented Programming (OOP) is a programming paradigm centered around real-world entities
known as objects.
C++ is one of the earliest and strongest OOP languages, implementing the four pillars of OOP:
1. Encapsulation
2. Inheritance
3. Polymorphism
4. Abstraction (covered indirectly through encapsulation & inheritance)
These pillars make software modular, reusable, secure, and maintainable, which is essential for large-
scale applications.
2. ENCAPSULATION
2.1 Definition
Encapsulation is the process of wrapping data (variables) and functions (operations) into a single unit
(class).
It protects data from outside interference and misuse by using access specifiers.
Simple meaning:
→ Data hiding + data protection inside a class.
2.2 Key Features
1. Data Hiding
Private members can only be accessed through public functions.
Prevents accidental modification.
2. Access Control using Access Specifiers
private → visible only inside class
public → accessible to all
protected → visible to class & subclasses
3. Getter & Setter Methods
Provide safe access to private data.
2.3 Example of Encapsulation
class Student {
private:
int age;
public:
void setAge(int a) {
if(a >= 5 && a <= 25)
age = a;
int getAge() {
return age;
};
Here, direct access is restricted, ensuring safe modifications.
2.4 Advantages of Encapsulation
Protects data integrity
Increases security
Makes code modular and maintainable
Allows validation before assigning data
Reduces complexity
2.5 Real-Life Examples
ATM PIN security
Private bank account balance
Car dashboard controls (internal mechanism hidden)
3. INHERITANCE
3.1 Definition
Inheritance allows a class (derived/child class) to acquire the properties and behaviors of another class
(base/parent class).
It promotes code reusability and establishes a hierarchical relationship.
3.2 Syntax
class Derived : access Base {
// new members
};
Example:
class Animal {
public:
void eat() { cout << "Eating\n"; }
};
class Dog : public Animal {
public:
void bark() { cout << "Barking\n"; }
};
3.3 Types of Inheritance in C++
1. Single Inheritance
One base → one derived class
A→B
2. Multilevel Inheritance
Chain of inheritance
A→B→C
3. Multiple Inheritance
Derived class inherits from multiple classes
A&B→C
4. Hierarchical Inheritance
One base class with multiple derived classes
A → B,
A→C
5. Hybrid Inheritance
Combination of above types.
3.4 Access Specifiers and Inheritance
Base Member public inheritance protected inheritance private inheritance
public public protected private
protected protected protected private
private inaccessible inaccessible inaccessible
3.5 Constructors in Inheritance
Base class constructor executes first
Then derived class constructor
Destructors follow reverse order
3.6 Example of Multilevel Inheritance
class A {
public:
void showA() { cout << "A\n"; }
};
class B : public A {
public:
void showB() { cout << "B\n"; }
};
class C : public B {
public:
void showC() { cout << "C\n"; }
};
3.7 Advantages of Inheritance
Reusability of code
Reduces duplication
Supports hierarchical structure
Enables polymorphism
3.8 Problems in Inheritance
Ambiguity in multiple inheritance
Complexity increases
Overuse can reduce flexibility
3.9 Real-Life Examples
Vehicle → Car → SportsCar
Employee → Manager → RegionalManager
Organism → Animal → Mammal → Human
4. POLYMORPHISM
4.1 Definition
Polymorphism means one name, many forms.
It allows functions or operators to behave differently depending on the context.
Two major types:
1. Compile-time Polymorphism (Static)
2. Run-time Polymorphism (Dynamic)
4.2 COMPILE-TIME POLYMORPHISM
(A) Function Overloading
Same function name, different parameter types/number.
class Print {
public:
void show(int a) { cout << a; }
void show(float b) { cout << b; }
void show(string c) { cout << c; }
};
(B) Operator Overloading
Operators are given new meaning for user-defined objects.
class Complex {
public:
int a, b;
Complex operator+(Complex obj) {
Complex temp;
temp.a = a + obj.a;
temp.b = b + obj.b;
return temp;
};
4.3 RUN-TIME POLYMORPHISM
Achieved using:
Function overriding
Virtual functions
Dynamic binding
(A) Function Overriding
Derived class redefines a base class function with the same signature.
class A {
public:
virtual void show() { cout << "A show"; }
};
class B : public A {
public:
void show() { cout << "B show"; }
};
(B) Virtual Functions
Ensures that the actual object’s function is executed, not the pointer type.
A *ptr;
B obj;
ptr = &obj;
ptr->show(); // calls B's show()
(C) Pure Virtual Functions & Abstract Classes
class Shape {
public:
virtual void draw() = 0; // pure virtual
};
Any class containing a pure virtual function becomes an abstract class and cannot be instantiated.
4.4 Advantages of Polymorphism
Enables flexibility and dynamic behavior
Allows one interface for multiple actions
Simplifies code maintenance
Supports frameworks and plug-in architecture
4.5 Real-Life Examples
Polymorphism in real world:
“Print” button → prints text, image, PDF, etc.
“Draw” function → line, circle, rectangle based on object
Messaging apps → send text/audio/video using one function
5. DIFFERENCES (Frequent Exam Questions)
Encapsulation vs Inheritance
Encapsulation. Inheritance
Bundles data + methods. Acquires features from another class
Focus on security. Focus on reusability
Achieved using classes and access modifiers Achieved using : operator
Hides implementation Creates hierarchy
Inheritance vs Polymorphism
Inheritance. Polymorphism
Parent-child relationship One function, many behaviors
Extends class. Specializes behavior
Compile-time or run-time Mostly run-time for overriding
Encapsulation vs Polymorphism
Encapsulation. Polymorphism
Hides data. Same interface with different actions
Protects data. Adds flexibility
6. SHORT PROGRAM COVERING ALL THREE PILLARS
#include <iostream>
using namespace std;
// Encapsulation
class Animal {
protected:
string name;
public:
void setName(string n) { name = n; }
virtual void sound() { cout << "Some sound"; } // Polymorphism
};
// Inheritance
class Dog : public Animal {
public:
void sound() { cout << name << " barks"; }
};
int main() {
Animal *ptr;
Dog d;
[Link]("Rocky");
ptr = &d;
ptr->sound(); // Runtime Polymorphism
Encapsulation: Binding data and functions; ensures data hiding using access specifiers.
Inheritance: Reusing and extending existing classes; supports hierarchies.
Polymorphism: Same interface, different behavior; achieved via overloading & overriding.
These pillars form the backbone of OOP and make programs modular, secure, efficient, and easy to
maintain.
OPERATOR & FUNCTION OVERLOADING
1. INTRODUCTION TO OVERLOADING
C++ supports a powerful feature called overloading, which allows the same name (function name or
operator symbol) to perform different tasks based on the context or data type.
This is a major part of compile-time polymorphism, one of the pillars of Object-Oriented Programming.
Why Overloading?
Increases code clarity
Makes programs more intuitive
Allows natural use of operators for user-defined types
Supports reusable and modular design
There are two main types:
1. Function Overloading
2. Operator Overloading
2. FUNCTION OVERLOADING
Function overloading means multiple functions can have the same name but must differ in:
Number of parameters, OR
Type of parameters, OR
Order of parameters.
Return type is not considered for overloading.
2.1 RULES FOR FUNCTION OVERLOADING
A function can be overloaded if:
1. Function name is same.
2. Parameter list must differ.
3. Return type alone cannot overload.
4. Default parameters must not cause conflicts.
5. Overload resolution happens at compile time.
2.2 NEED FOR FUNCTION OVERLOADING
Allows performing similar operations on different data types
Improves readability
Supports type flexibility
Enables polymorphic behavior
2.3 EXAMPLES OF FUNCTION OVERLOADING
Example 1: Add integers, floats, and doubles
int add(int a, int b);
float add(float a, float b);
double add(double a, double b);
Example 2: Area calculation using overloading
float area(int r); // circle
float area(int l, int b); // rectangle
float area(float a, float b); // parallelogram
2.4 FUNCTION OVERLOADING WITH DIFFERENT PARAMETERS
(i) Different number of parameters
void print(int);
void print(int, int);
(ii) Different type of parameters
void show(int);
void show(float);
(iii) Different order of parameters
void display(int, float);
void display(float, int);
3. OPERATOR OVERLOADING
Operator overloading allows C++ operators (+, -, ==, ++, etc.) to work with user-defined types (objects).
Example:
If we have a class Complex, adding two objects using:
c3 = c1 + c2;
is not possible unless the + operator is overloaded.
3.1 WHY OPERATOR OVERLOADING?
Gives natural and intuitive meaning to user-defined objects
Extends the behavior of built-in operators
Supports abstraction (e.g., Matrix + Matrix)
Makes object interaction easy and readable
3.2 SYNTAX OF OPERATOR OVERLOADING
Using member function
returnType operator <symbol> (parameters)
Using friend function
friend returnType operator <symbol> (parameters);
3.3 RULES FOR OPERATOR OVERLOADING
1. At least one operand must be a user-defined type.
2. Cannot overload:
:: (scope resolution)
. (member access)
.*
?: (ternary)
sizeof
typeid
3. Overloading cannot change:
Precedence
Associativity
Number of operands
4. Operators must maintain natural meaning and not confuse users.
4. TYPES OF OPERATORS THAT CAN BE OVERLOADED
Arithmetic Operators:
+, -, *, /, %
Unary Operators:
++, --, !, ~
Relational Operators:
==, !=, <, >, <=, >=
Logical Operators:
&&, ||
Assignment Operators:
=, +=, -=
Bitwise Operators:
&, |, <<, >>
Other Operators:
[], (), new, delete, ->, ->*
5. OPERATOR OVERLOADING USING MEMBER FUNCTION
Example: Overloading + for Complex Numbers
class Complex {
int real, imag;
public:
Complex(int r=0, int i=0) { real = r; imag = i; }
Complex operator + (Complex c) {
Complex temp;
[Link] = real + [Link];
[Link] = imag + [Link];
return temp;
};
Usage:
Complex c3 = c1 + c2;
6. OVERLOADING UNARY OPERATORS
Example: Prefix ++
class A {
int x;
public:
A(int a=0) { x = a; }
void operator ++() { x = x + 1; }
};
Example: Postfix ++
A operator ++ (int) {
A temp = *this;
x++;
return temp;
}
Note: Postfix takes a dummy int parameter.
7. OPERATOR OVERLOADING USING FRIEND FUNCTIONS
When left operand is not an object of the class (e.g., cout << obj), friend overloading is required.
Example: Overloading << and >>
class Test {
public:
int x;
friend ostream& operator << (ostream &out, Test &t) {
out << t.x;
return out;
friend istream& operator >> (istream &in, Test &t) {
in >> t.x;
return in;
};
8. OVERLOADING ASSIGNMENT OPERATOR =
Used for deep copy (important when pointers are involved).
Test& operator = (const Test &t) {
this->x = t.x;
return *this;
9. OVERLOADING RELATIONAL OPERATORS
Example: Compare sizes
bool operator > (Box b) {
return volume() > [Link]();
10. OVERLOADING SUBSCRIPT OPERATOR []
Useful for custom indexing.
int& operator [] (int index) {
return arr[index];
11. OVERLOADING FUNCTION CALL OPERATOR ()
Allows objects to be used like functions.
void operator() () {
cout << "Object Called!";
Usage:
obj();
12. OPERATOR OVERLOADING BEST PRACTICES
Maintain natural operator meaning
Avoid unnecessary overloading
Use friend only when necessary
For binary operators, pass object by const reference
Return objects by value (optimized by compiler)
Ensure no ambiguity between overloaded operators
13. DIFFERENCE: FUNCTION VS OPERATOR OVERLOADING
Feature. Function Overloading. Operator Overloading
Based on. Function name. Operator symbol
Purpose. Same task, different data Extend operator functionality
Types. . Compile-time polymorphism Compile-time polymorphism
Ease. Simple More complex
Friend keyword Not needed. Sometimes needed
14. REAL-LIFE USE CASES OF OPERATOR OVERLOADING
1. Complex number addition
2. Vector and Matrix operations
3. String concatenation
4. Big integer arithmetic
5. Smart pointers (->, *)
6. File handling classes
7. Data structures like pair, tuple, map
15. EXAM-LEVEL SHORT NOTES
Function Overloading
Same name
Different parameters
Compile-time binding
Operator Overloading
Same operators for objects
Must maintain natural meaning
Some operators cannot be overloaded
Syntax
returnType operator+(parameters);
Below are very detailed, 5-page–equivalent long notes on
Inheritance Types & Access Specifiers in C++,
crafted in clear, exam-oriented language to help you score 10/10 CGPA.
INHERITANCE TYPES & ACCESS SPECIFIERS
1. INTRODUCTION TO INHERITANCE
Inheritance is one of the fundamental features of Object-Oriented Programming (OOP).
It allows one class (child/derived class) to acquire the properties and behaviours of another class
(parent/base class).
Definition:
Inheritance is the process in which one class inherits the data members and member functions of
another class, enabling code reuse and hierarchical classification.
Advantages:
Promotes reusability
Reduces code duplication
Supports hierarchical design
Enables extensibility (easy to update/modify)
Helps achieve polymorphism
2. TERMINOLOGY OF INHERITANCE
Base Class: The class whose properties are inherited
Derived Class: The class that acquires properties
Protected Members: Accessible only in derived classes
Access Mode: Defines how base class members are inherited
Hierarchical Relationship: Tree-like structure of classes
General Syntax
class Derived : access_mode Base {
// new members
};
3. ACCESS SPECIFIERS
Access specifiers determine the visibility of class members inside and outside the class.
C++ provides three access specifiers:
3.1 PUBLIC Access
Members are accessible everywhere
Accessible inside class, outside class, and in derived classes
Example:
class A {
public:
int x;
};
3.2 PRIVATE Access
Accessible only within the same class
Not accessible outside the class
Not inherited publicly in derived classes
If inherited, they become inaccessible, even in derived class
Example:
class A {
private:
int x;
};
3.3 PROTECTED Access
Accessible within the class
Accessible within derived classes
Not accessible outside
Example:
class A {
protected:
int x;
};
Protected is crucial in inheritance because it allows derived classes to access parent’s data, but still hides
them from the outside world.
4. EFFECT OF ACCESS SPECIFIERS DURING INHERITANCE
When deriving a class, we also specify an access mode:
class Derived : public Base
class Derived : private Base
class Derived : protected Base
This mode determines how public and protected members of the base class are inherited.
4.1 Inheritance Access Table
Base Class Members Public Inheritance Protected Inheritance Private Inheritance
Public Public in Derived Protected in Derived Private in Derived
Protected Protected Protected Private
Private Not accessible Not accessible Not accessible
5. TYPES OF INHERITANCE
C++ supports five main types of inheritance:
1. Single Inheritance
2. Multiple Inheritance
3. Multilevel Inheritance
4. Hierarchical Inheritance
5. Hybrid Inheritance
We will study all with explanations, diagrams, examples, and use cases.
5.1 SINGLE INHERITANCE
A single base class and a single derived class.
Diagram:
A → B
Example:
class A {
public:
int x;
};
class B : public A {
public:
void show() { cout << x; }
};
Use Cases:
Extending simple classes
Adding new functionality
5.2 MULTIPLE INHERITANCE
A derived class inherits from more than one base class.
Diagram:
A B
\ /
Example:
class A { public: int x; };
class B { public: int y; };
class C : public A, public B {
public:
int sum() { return x + y; }
};
Issues:
Name ambiguity
Diamond problem (solved by virtual inheritance)
5.3 MULTILEVEL INHERITANCE
Inheritance occurs across multiple levels (like a chain).
Diagram:
A→B→C
Example:
class A { public: int x; };
class B : public A { public: int y; };
class C : public B { public: int z; };
Use Cases:
Class extensions in multiple stages
Real-world hierarchical models
5.4 HIERARCHICAL INHERITANCE
One base class and multiple derived classes.
Diagram:
/|\
B C D
Example:
class A { public: int x; };
class B : public A {};
class C : public A {};
class D : public A {};
Use Cases:
Base functionality given to multiple child classes
OOP modeling (e.g., Animals → Dog, Cat, Horse)
5.5 HYBRID INHERITANCE
A combination of two or more types of inheritance.
Diagram:
/ \
B C
\ /
Example:
class A { public: int x; };
class B : public A {};
class C : public A {};
class D : public B, public C {};
Issue:
Diamond Problem
→ Causes multiple copies of base class members
Solution: Virtual Inheritance
class B : virtual public A {};
class C : virtual public A {};
6. VIRTUAL INHERITANCE
Solves the diamond problem by ensuring that only one copy of base class is inherited.
Example:
class A { public: int x; };
class B : virtual public A {};
class C : virtual public A {};
class D : public B, public C {};
After virtual inheritance:
Only one instance of class A exists inside D.
7. CONSTRUCTORS IN INHERITANCE
When an object of the derived class is created:
1. Base class constructor executes first
2. Derived class constructor executes second
Order of destruction is opposite.
Example:
class A {
public:
A() { cout << "A"; }
};
class B : public A {
public:
B() { cout << "B"; }
};
Output:
AB
8. FUNCTION OVERRIDING
A feature where derived class redefines a function of the base class.
Rules:
Same name
Same parameters
Same return type
Base class function must be virtual (for runtime polymorphism)
9. ACCESS CONTROL SUMMARY
Access Specifier Own Class Derived Class. Outside
Public. Yes. Yes. Yes
Protected. Yes. Yes. No
Private Yes. No. No
10. REAL-LIFE EXAMPLES OF INHERITANCE
Cars
Vehicle (base)
Car (derived)
SportsCar (derived)
Employees
Employee
↓
Manager
HRManager
Animals
Animal
→ Dog
→ Cat
→ Elephant
11. DIFFERENCE BETWEEN PUBLIC, PRIVATE & PROTECTED INHERITANCE
Feature. Public Private Protected
Use Case General inheritance Implementation hiding Secure inheritance
Base Public Members Public Private Protected
Base Protected Members Protected Private Protected
Base Private Members Inaccessible Inaccessible Inaccessible
12. IMPORTANT EXAM QUESTIONS (THEORY)
1. Define inheritance. What are its advantages?
2. Explain types of inheritance with diagrams.
3. What is multiple inheritance? Give example.
4. Explain access specifiers in C++.
5. Differences between protected and private inheritance.
6. Explain virtual inheritance and diamond problem.
7. What is hierarchical and multilevel inheritance?
13. IMPORTANT EXAM PROGRAMS
1. Program on Single Inheritance
2. Program on Multiple Inheritance
3. Virtual inheritance example
4. Constructor order in inheritance
5. Program showing access specifiers
VIRTUAL FUNCTIONS, ABSTRACT CLASSES, PURE VIRTUAL FUNCTIONS & VIRTUAL BASE CLASSES**
1. INTRODUCTION
Polymorphism is one of the major pillars of Object-Oriented Programming (OOP).
C++ achieves runtime polymorphism through:
Virtual functions
Abstract classes
Pure virtual functions
Virtual base classes
These concepts ensure dynamic behaviour, extensibility, and memory-efficient inheritance.
2. VIRTUAL FUNCTIONS
A virtual function is a member function in the base class that is declared with the keyword virtual and
redefined in the derived class.
Its primary purpose is to support runtime (dynamic) polymorphism through late binding.
Definition:
A virtual function is a function that is resolved at runtime depending on the type of object pointed to by
a base class pointer.
2.1 Why Do We Need Virtual Functions?
Normally, C++ uses early binding:
Base *b;
Derived d;
b = &d;
b->show(); // calls Base version (wrong)
But with virtual, binding happens at runtime, and now correct function executes:
virtual void show();
2.2 Features of Virtual Functions
Support runtime polymorphism
Must be member of a class
Defined using virtual keyword in base class
Invoked using base class pointer/reference
Must be overridden in derived class
Cannot be static
Resolves function call at runtime via V-Table
Destructors can also be made virtual
2.3 Example of Virtual Function
class Base {
public:
virtual void show() {
cout << "Base class";
};
class Derived : public Base {
public:
void show() override {
cout << "Derived class";
};
int main() {
Base *ptr;
Derived d;
ptr = &d;
ptr->show(); // Output: Derived class
3. VIRTUAL TABLE (V-TABLE) & V-PTR
When a class contains virtual functions, C++ creates:
1. V-Table:
A lookup table storing addresses of overridden functions.
2. V-Pointer:
A hidden pointer in each object that points to the V-Table.
This enables runtime function resolution.
4. ABSTRACT CLASSES
An abstract class is a class that cannot be instantiated and is only used as a base class for inheritance.
An abstract class:
Contains at least one pure virtual function
Cannot create objects
Can have normal functions
Can have data members
Can have constructors & destructors
Purpose:
To create a generic base class for further specialized derived classes.
4.1 Example of Abstract Class
class Shape {
public:
virtual void area() = 0; // pure virtual function
};
class Circle : public Shape {
public:
void area() override {
cout << "Area of circle";
};
int main() {
Shape *s; // allowed
// Shape obj; // error: cannot instantiate abstract class
Circle c;
s = &c;
s->area();
5. PURE VIRTUAL FUNCTIONS
A pure virtual function is a virtual function with no body in base class.
It forces derived classes to implement their own version.
Syntax:
virtual void function() = 0;
Purpose:
Provide a function interface
Enforce overriding
Support abstract class creation
5.1 Characteristics of Pure Virtual Functions
Cannot have implementation in base class
Makes the class abstract
All derived classes must override it
Provides a uniform interface for all derived classes
5.2 Example
class Animal {
public:
virtual void sound() = 0;
};
Derived class:
class Dog : public Animal {
public:
void sound() override {
cout << "Bark";
};
6. DIFFERENCE BETWEEN VIRTUAL FUNCTIONS AND PURE VIRTUAL FUNCTIONS
Virtual Function. Pure Virtual Function
Has definition in base class. No definition in base class
Overriding is optional. Overriding is mandatory
Base class can be instantiated Base class becomes abstract
Achieves runtime polymorphism Achieves runtime polymorphism + abstraction
7. VIRTUAL BASE CLASSES
Virtual base classes are used to eliminate duplication of base class members in multiple inheritance.
Why Virtual Base Class?
To solve the Diamond Problem.
7.1 Diamond Problem
Consider:
/\
B C
\/
B and C inherit from A, and D inherits from both B and C.
Thus, D gets two copies of A's data — ambiguity occurs.
7.2 Solution: Virtual Inheritance
class A {
public:
int x;
};
class B : virtual public A {};
class C : virtual public A {};
class D : public B, public C {};
Now, only one copy of A exists inside D.
8. WORKING OF VIRTUAL BASE CLASSES
Compiler ensures only one shared instance
Virtual inheritance uses virtual base pointer (vbptr)
Ensures consistency during construction/destruction
Constructor Calling Order in Virtual Inheritance:
1. Virtual base classes
2. Non-virtual base classes
3. Derived class
9. EXAMPLES & PROGRAMS
Example 1: Virtual Function + Runtime Polymorphism
class A {
public:
virtual void display() { cout << "A"; }
};
class B : public A {
public:
void display() override { cout << "B"; }
};
Example 2: Abstract Class + Pure Virtual
class Shape {
public:
virtual float area() = 0;
};
Example 3: Virtual Base Class
class Person {
public:
string name;
};
class Student : virtual public Person {};
class Employee : virtual public Person {};
class WorkingStudent : public Student, public Employee {};
10. ADVANTAGES OF VIRTUAL FUNCTIONS & ABSTRACT CLASSES
Advantages of Virtual Functions
Enables runtime polymorphism
Clean extensible design
Flexible code architecture
Reduces coupling
Supports overriding and interface changes
Advantages of Abstract Classes
Enforces structure
Provides a common interface
Useful in hierarchical classification
Improves code abstraction
Advantages of Virtual Base Classes
Removes ambiguity in multiple inheritance
Prevents duplicate members
Better memory management
Clean inherited structure
11. APPLICATIONS & USE-CASES
Virtual Functions
GUI libraries
Game engines
Device drivers
Event-driven programming
Abstract Classes
Framework design
Database access interfaces
Hardware abstraction layers
Shape hierarchy (geometry)
Virtual Base Classes
Complex inheritance hierarchies
Large-scale software modeling
Avoiding data redundancy
12. IMPORTANT EXAM QUESTIONS
1. Explain virtual functions with example.
2. Define abstract class. How is it different from a normal class?
3. What are pure virtual functions?
4. Explain virtual base class with neat diagram.
5. Discuss the diamond problem in C++.
6. Compare virtual function and pure virtual function.
7. Describe the role of V-Table and V-Pointer.
13. SUMMARY (1-PAGE REVISION)
Virtual Function: resolves at runtime
Pure Virtual Function: must be overridden
Abstract Class: cannot be instantiated
Virtual Base Class: solves diamond problem