Computational Thinking and Problem
Solving with C & Python
Module III: Arrays, Pointers, &
Structure
[Link]. Year I Semester I (2025-2029)
All Sections
C Foundations- 10 Lecture Hours
✓ One-dimensional and multi-dimensional arrays
✓ Array operations and Pointers
✓ Pointer and arrays
✓ Pointers and functions Module III
✓ Dynamic memory allocation Outline
✓ Defining and using structures
✓ Array of structures, Nested structures
✓ Structure and pointer operations 2
Array – Overview
What is an Array?
An array is a collection of items of the same data type stored in
contiguous memory locations.
Why is it Important?
➢ Enables efficient access and manipulation of data.
➢ Simplifies data handling when dealing with large datasets.
➢ Simple and widely used data structure. 3
Basic Terminologies
Element: Individual item in an array.
Index: Position of an element (starts from 0 in most languages).
Example
int arr[5] = {10, 20, 30, 40, 50};
elements are 10, 20, 30, 40, 50.
arr[0] = 10, arr[4] = 50 4
Memory Representation
➢ Array Elements are stored sequentially in memory.
➢ Supports fast access using indices.
➢ Array elements are stored side by side in memory.
➢ This allows the computer to quickly find any element using its
index.
Example
If arr[0] is stored at address 1000, and each integer takes 4 bytes,
then arr[1] will be at address 1004. 5
Declaration of Array
This is the process of telling the compiler to create an array of a
specific type and size.
Example
int arr[5]; // Stores 5 integers
char name[10]; // Stores 10 characters
float marks[20]; // Stores 20 floating-point value 6
Initialization of Array
The process of given values to an arrays at the time of declaration is
called an initialization of array. E.g
i. int arr[] = {1, 2, 3, 4, 5};
ii. char letters[5] = {'a', 'b', 'c', 'd', 'e'};
iii. float scores[3] = {9.5, 8.0, 7.5};
You can also assign values later: arr[0] = 10; arr[1] = 20; 7
Types of Arrays
Arrays can be grouped based on size and dimension.
8
Array – Based on Size
Limitation
(a) Fixed Sized Array
Cannot change the size later.
Size is fixed during declaration.
Wastes memory if declared too
Memory is allocated at compile time.
large.
Example
int arr1[5]; // Empty array of 5 integers
int arr2[5] = {1,2,3,4,5}; // Fixed array with values
9
Array – Based on Dimension
(a) One-Dimensional Array (1-D)
Stores data in a single row or linear form.
Example
int marks[5] = {80, 75, 90, 60, 95};
Access: marks[0] = 80, marks[4] = 95
11
Array – Based on Dimension
(b) Multi-Dimensional Array
Stores data in rows and columns (like a table).
Example
int matrix[2][3] = {
{1, 2, 3},
{4, 5, 6}
};
Represents 2 rows and 3 columns.
12
Array Operations
Array Operation Explanation
Access Retrieving an element directly from the array using its index number.
Visiting or displaying each element of the array sequentially (forward or
Traversal
backward).
Insertion Adding a new element to the array — at the beginning, middle, or end.
Removing an element from the array; elements may need to shift to fill
Deletion
the gap.
Finding whether a specific value exists in the array (using linear or binary
Searching
search).
Sorting Arranging elements in a specific order (e.g., ascending or descending).
14
Operation Code Example Output / Explanation
int a[5] = {10, 20, 30, 40, Displays 30 (element at index
Access
50};\nprintf("%d", a[2]); 2).
int a[5] = {1,2,3,4,5};\nfor(int Prints 1 2 3 4 5 (visits all
Traversal
i=0;i<5;i++)\n printf("%d ", a[i]); elements).
Insertion int a[5] = {10,20,30,40};\na[4] = 50; Adds 50 at the end of the array.
int a[5] = {10,20,30,40,50};\nfor(int Removes element at index 2
Deletion
i=2;i<4;i++)\n a[i]=a[i+1]; (30).
int a[5]={10,20,30,40,50};\n int
Searching
key=30;\nfor(int i=0;i<5;i++)\n Finds 30 at index 2.
(Linear)
if(a[i]==key)\n printf("Found at %d",i);
int a[5]={40,10,50,20,30};\nfor(int
Sorting i=0;i<5;i++)\n for(int j=i+1;j<5;j++)\n After sorting → 10 20 30 40
(Ascending) if(a[i]>a[j]){\n int 50.
11/24/2025 t=a[i];a[i]=a[j];a[j]=t;\n
Computational Thinking}
and Problem Solving with Python 15
Pointers- declaration, dereferencing, arithmetic
What is a Pointer?
➢ A pointer is a variable that stores the memory address of
another variable.
➢ Pointers allow programmers to directly interact with memory —
one of the most powerful features of C.
16
Declaring a Pointer
A pointer is declared using an asterisk * before the pointer name.
Syntax
data_type* name;
17
Initializing a Pointer
Assign an address to a pointer using the address-of operator (&).
Example
Note
Declaration and initialization can be done in one line — this is called pointer
definition.
18
Example
19
Dereferencing a Pointer
The dereference operator (*) is used to access the value stored at
the memory address.
Example
20
Printing Pointers Correctly
Use %p instead of %d when printing addresses.
21
Size of Pointers
The size of a pointer depends on the system architecture, not on
the data type. All pointers occupy the same space since they store
memory addresses, not data.
Pointer
System Type
Size
32-bit system 4 bytes
64-bit system 8 bytes
22
Special Types of Pointers
Type Description Example
Points to nothing. Used to
NULL Pointer int *ptr = NULL;
check if a pointer is assigned.
Generic pointer — can hold the
Void Pointer void *ptr;
address of any data type.
Uninitialized pointer — may
Wild Pointer point to random memory, int *ptr; // no initialization
causing errors.
int *ptr =
Dangling Points to freed or deleted
malloc(sizeof(int));\nfree(ptr);\n
Pointer memory.
ptr = NULL;
Key Tip: Always initialize pointers and set them to NULL after freeing memory.
23
Pointer Arithmetic
You can perform limited arithmetic operations on pointers,
mainly involving movement between memory addresses.
Operation Description Example
Increment / Moves pointer forward or backward by one
ptr++, ptr--
Decrement element.
Add / Subtract Integer Moves pointer by n elements. ptr = ptr + 2;
Finds number of elements between two
Subtract Two Pointers ptr2 - ptr1
addresses.
Check if two pointers point to the same
Compare Pointers if (ptr1 == ptr2)
address.
Assign NULL Reset a pointer safely. ptr = NULL; 24
Example
When incremented (ptr++), the pointer moves to the next memory
location of the same data type.
11/24/2025 Computational Thinking and Problem Solving with Python 25
Pointers and Arrays
Whenever an array is declared, the compiler allocates memory for
its elements in continuous memory locations and creates a
constant pointer that stores the base address of the array — that
is, the address of its first element.
27
Example 2: Accessing Elements Using Pointer
Arithmetic
Key Idea:
Since elements are stored consecutively, you can move between them using pointer
arithmetic:
Increment (ptr++) moves to next element
Decrement (ptr--) moves to previous element
Addition/Subtraction of integers shifts pointer position 30
Constant Pointers
When a pointer is declared constant, it means the address
stored in the pointer cannot be changed after initialization —
though the value at that address can be modified.
➢ ptr always points to
the same memory
location (a).
➢ You can modify the
value of a via *ptr,
but you cannot make
ptr point to another
variable. 31
Pointers and functions
In the c programming language, there are two ways to pass
parameters to functions.
i. Call by Value
ii. Call By Reference
In call by reference, pointer variables are used as formal
parameters, and the address of actual parameters is passed from
the calling function to the called function.
32
Example
33
Dynamic Memory Allocation
Dynamic memory allocation is the process of allocating
the memory manually at the run time.
Why it matters?
➢ Handles data of unknown or varying size.
➢ Uses the heap, not the stack.
➢ Memory persists after a function returns (unlike local variables).
➢ Size can be expanded or reduced.
➢ Must be manually freed to avoid memory leaks. 34
Dynamic Memory Allocation
The <stdlib.h> library provides four key functions for
implementation of dynamic memory allocation.
These functions are: Function Syntax
i. malloc() malloc() void* malloc(size_in_bytes);
ii. calloc() void* calloc(num_blocks,
calloc()
size_of_each_block);
iii. realloc()
realloc() void* realloc(pointer, new_size);
iv. free()
free() void free(pointer);
35
1. malloc() — Memory Allocation
Allocates a single block of
memory.
Contains garbage values
(uninitialized).
Returns NULL if allocation fails.
36
2. calloc() — Contiguous Allocation
➢ Like malloc() but initializes memory to zero.
➢ Good for arrays.
Output
37
3. free() — Release Memory
Frees allocated memory.
Avoids memory leaks.
Set pointer to NULL after freeing.
38
4. realloc() — Resize Memory
➢ Expands or shrinks an existing block.
➢ Use a temporary pointer to avoid losing the original block if
reallocation fails.
Output
39
Quick Practical Flow
Allocate → malloc() / calloc()
Use memory
Resize if needed → realloc()
Free memory → free()
40
Defining and Using Structures
➢ A structure is a user-defined data type that allows grouping of
different kinds of data under a single name.
➢ It is created using the struct keyword.
➢ Each item inside a structure is called a member and can have any
valid data type (int, float, char, array, pointer, etc., structure).
➢ They are the building blocks for advanced data structures like
linked lists, trees, and more.
41
Why Structures Are Useful
Structures allow programmers to:
➢ Combine different data types in one unit
➢ Organize related data (e.g., student details: name, roll, marks)
➢ Build complex data structures (linked lists, trees, graphs)
42
Structures: Definition, Usage, & Operations
Defining a Structure
A structure in C is defined using the struct keyword.
It is also called a structure template or structure prototype
because no memory is allocated at this point.
Syntax
struct structure_name {
data_type1 member1;
data_type2 member2;
...
};
Don’t forget the semicolon after the closing brace.
43
Structures: Definition, Usage, & Operations
Creating Structure Variables
After defining a structure, create its variables like any other variable:
struct structure_name var;
Variables can also be declared along with the structure definition:
struct structure_name {
...
} var1, var2;
44
Example
➢A structure named ‘A’ is
defined with a single integer
member ‘x’.
➢Inside main(), a structure
variable ‘a’ is declared.
➢The member x is accessed
and assigned using the dot
operator (.).
➢The value stored in a.x is
printed. 45
Basic Operations on Structures
1. Access Structure Members
Use the dot operator when accessing through a structure variable:
[Link];
Use the arrow operator when accessing through a pointer:
ptr->member;
46
Initializing Structure Members
Variables cannot be initialized inside structure definition.
struct A { int x = 10; }; // Error
Because memory is allocated only when a structure variable is
created.
47
Correct Ways to Initialize
1. Default Initialization
struct A a = {0}; // all members = 0
2. Assign After Declaration
struct A a;
a.member1 = value; (Cannot directly assign arrays/strings.)
3. Initializer List
struct A a = {value1, value2, ...};
4. Designated Initialization
struct A a = { .member1 = value1, .member2 = value2 };
48
Example
Output
49
Copy Structure
Structures can be copied directly using the assignment operator.
Example: s2 = s1;
This performs shallow copy
If the structure contains pointers to dynamically allocated memory,
only the pointers are copied—not the actual data.
50
Example of Structure copy
51
Passing Structures to Functions
Structures can be passed:
By value → Copy is passed
By pointer → Recommended for large structures
52
Example
Output
53
Using typedef with Structures
typedef allows you to create a shorter alias for a structure.
Output
54
Size of Structures: Padding and Packing
The size of a structure is not always equal to the sum of its members
due to structure padding.
Structure Padding
The compiler adds extra bytes so data members align naturally in memory.
This improves CPU access speed.
Structure Packing- Removes or minimizes padding.
Used when memory needs to be tightly packed (no padding).
Two methods: Padding may slow down access because the
#pragma pack(1) CPU must handle unaligned data.
__attribute__((packed)) 55
Array of structures
An array of structures allows storing multiple structure variables
under a single name. This helps when handling collections of
related records such as students, employees, books, or products.
Each array element stores a full structure with its own member
values.
56
Array of Structure Declaration
Declaring an array of structures works just like declaring an array of
basic data types. After defining a structure, an array to store
multiple structure instances can be created, making it easy to
manage many related records efficiently.
Syntax
struct struct_name arr_name[size];
57
Need for Array of Structures
With large datasets, creating separate structure variables is
impractical. For example, a company of or 1000 employees,
manually declaring struct Employee emp1, emp2, emp3, ...; is
impractical
Instead, use:
struct Employee emp[1000];
58
Need for Array of Structures
Benefits
i. Efficient for managing large datasets
ii. Easy to scan, sort, update, and search
iii. Useful for databases like employee records, students, products,
etc.
59
Basic Operations on Array of Structures
Description Example Code Output
struct A {\n int var;\n char
Nested Initializer List 1a
c;\n};\n\nstruct A arr1[2] = {\n
(Recommended) 2b
{1, 'a'},\n {2, 'b'}\n};\n
Non-Nested
struct A arr2[2] = { 10, 'A', 20, 10 A
Initialization (Not
'B' };\n 20 B
recommended)
struct A arr3[2] = {\n { .c = 'A',
Designated 10 A
.var = 10 },\n { .var = 2, .c = 'b'
Initialization (GNU C) 2b
}\n};\n 60
Example: Storing Student Information
Output
62
Finding the Size of an Array of Structures
Structure padding affects size.
Let’s calculate the size of the array:
The size of array structure can be
determined using sizeof keyword
Output
63
Nested Structures
Nested structures allow one structure to exist as a member
inside another structure.
This makes them powerful tools for representing real-world hierarchical data
such as students inside colleges or employees inside organizations. There are
two ways to nest one structure into another:
i. Embedded Structure Nesting
ii. Separate Structure Nesting
Each method has advantages in terms of reusability, clarity, and code
organization.
64
Creating Embedded Nested Structures
Syntax for creating nested structure:
struct A {
member;
struct B {
member;
} var1;
} var2;
65
Embedded Structure Nesting
The child structure is declared inside the parent structure.
Case 1 — Error if Variable Missing
When embedding a structure, the inner structure must end with a variable
name. Without this variable, the structure exists only as a definition and
cannot be accessed, causing compilation errors.
66
Embedded Structure Nesting
The child structure is declared inside the parent structure.
Case 2 — Correct Method
Declaring a structure variable at the end of the inner structure creates an
accessible instance inside the parent structure. This ensures the embedded
structure is fully usable.
67
Accessing Nested Members
To access nested members, use the dot operator “.”
repeatedly.
Syntax:
[Link];
Output
68
Accessing Nested Structures
Nested structures can be accessed by two methods:
i. Normal variables (using dot operator)
ii. Pointers (using arrow operator)
➢ Accessing inner structure members extends the dot chain, with
each dot indicating a deeper level.
➢ Pointers to nested structures use arrows to dereference and
dots to access inner members. 69
Drawbacks of Nested Structures
i. Embedded structures cannot be created outside their parent,
reducing flexibility when separate instances are needed.
ii. Embedded structures are limited to one parent and cannot be
shared, reducing modularity.
NOTE: Self-nesting is disallowed because it causes infinite recursive
memory allocation. 70
Passing Nested Structure to Functions
Nested structures can be passed to functions either by:
i. Passing entire nested structure
ii. Passing Nested Structure Members
Direct passing is convenient, whereas passing members allows
more selective data handling.
71
Passing Nested Structure to Functions
➢ Passing the entire structure simplifies function calls and ensures
all necessary data travels together. The function receives a
complete copy of the structure.
➢ Passing by structure members sends only the required data to
the function, reducing overhead but requiring more parameters.
It is useful when only specific values need to be processed. 72
Passing Entire Nested Structure
Output
73
Passing Nested Structure Members
Output
74
Structure and Pointer Operations
What is a Structure Pointer?
➢ A structure pointer stores the address of a structure
variable.
➢ It allows accessing structure members directly through
memory address, improving efficiency.
Syntax
struct struct_name *pointer_name;
75
Structure and Pointer Operations
Output
30
ptr->var accesses the member using the pointer. 76
Accessing Structure Members via Pointer
There are two methods for assessing the structure member
through pointer:
i. Dereference + Dot Operator ((*ptr).member)
ii. Arrow Operator (->) (ptr->member)
➢ The arrow operator is the most commonly used.
➢ It is short and easy to read
77
Why Use Arrow Operator?
➢ Direct access to structure members
➢ Cleaner and more readable than (*ptr).member
78
Why Use Arrow Operator?
Output
79
Summary
➢ Structure pointers help efficiently manipulate structures.
➢ Dereference + dot and the arrow operator both work, but -> is
preferred.
➢ Used widely in functions, dynamic memory, and linked data
structures.
80
Thank You
81