0% found this document useful (0 votes)
3 views135 pages

CPP Notes For College

The document covers advanced C++ concepts including function nesting, recursion, and command-line arguments. It explains the importance of nesting for modularity and code reusability, details the structure and types of recursion, and introduces command-line arguments for runtime data input. Additionally, it discusses the use of arrays and pointers in function arguments, highlighting their advantages and limitations.

Uploaded by

idikaco158
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views135 pages

CPP Notes For College

The document covers advanced C++ concepts including function nesting, recursion, and command-line arguments. It explains the importance of nesting for modularity and code reusability, details the structure and types of recursion, and introduces command-line arguments for runtime data input. Additionally, it discusses the use of arrays and pointers in function arguments, highlighting their advantages and limitations.

Uploaded by

idikaco158
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

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

You might also like