Module 2
Pointers
Pointers - pointer arithmetic, Pointers with Arrays and functions,
function pointers, Dynamic Memory Allocation.
Pointers
❖A pointer is a variable that stores the memory address of another variable as its
value.
❖A pointer variable points to a data type (like int) of the same type, and is created
with the * operator.
❖Pointers are essential for dynamic memory allocation, providing control over
memory usage with functions like malloc, calloc, and free.
❖Dereferencing operator(*) used to declare pointer variable and access the value
stored in the address.
❖Address operator(&) used to returns the address of a variable or to access the
address of a variable to a pointer.
2
Example
#include <stdio.h>
int main()
{
int m = 100;
int *ptr = &m; // Equivalent to int *ptr; ptr=&m;
printf("The Value of Variable m is: %d\n", m);
printf("The Value of Variable m is using pointer: %d\n", *ptr);
printf("The Memory Address of Variable m is: %p\n", &m);
printf("The Memory Address of Variable m is using ptr: %p\n", ptr);
return 0;
}
3
To store the string as a pointer
#include <stdio.h>
int main() {
// Storing string as pointer
char *s = “Welcome";
printf("%s", s);
return 0;
}
4
Types of Pointers in C
1. Integer Pointers
These are the pointers that point to the integer values.
Pointer to Integer.
Similarly, a pointer can point to any primitive data type and is named accordingly.
2. Array Pointer
Pointers and Array are closely related to each other. Even the array name is the pointer to its first element.
Pointer to Arrays.
3. Structure Pointer
The pointer pointing to the structure type
Pointer to Structure.
4. Function Pointers
Function pointers point to the functions.
They are different from the rest of the pointers in the sense that instead of pointing to the data, they point to
the code.
5. Double Pointers
We can define a pointer that stores the memory address of another pointer.
Pointers-to-pointer.
5
Types of Pointers in C
6. NULL Pointer
The Null Pointers are those pointers that do not point to any memory location.
They can be created by assigning a NULL value to the pointer.
A pointer of any type can be assigned the NULL value.
7. Void Pointer
The Void pointers in C are the pointers of type void.
It means that they do not have any associated data type.
Called generic pointers as they can point to any type and can be typecasted to any type.
8. Wild Pointers
The Wild Pointers are pointers that have not been initialized with something yet.
These types of C-pointers can cause problems in our programs and can eventually cause them to crash.
9. Constant Pointers
In constant pointers, the memory address stored inside the pointer is constant and cannot be modified once it is defined.
It will always point to the same memory address.
10. Pointer to Constant
The pointers pointing to a constant value that cannot be modified are called pointers to a constant.
Here we can only access the data pointed by the pointer, but cannot modify it. Although, we can change the address stored in
the pointer to constant.
6
Pointers and Arrays • We can use pointers to access arrays.
• The name of an array, is actually a pointer to the
first element of the array. - The memory address
of the first element is the same as the name of
#include <stdio.h> the array.
int main() {
int arr[3] = { 5, 10, 15 }; // Declare an array
printf("%d\n", arr[0]); // Access first element using index
printf("%d\n", *arr); // Access first element using pointer
printf(“%p\n”, arr); // Get the memory address of arr array
printf(“%p\n”, &arr[0]); // Get the memory address of first element of arr array
return 0;
}
7
Pointers and Arrays
#include <stdio.h>
int main() {
int arr[5] = { 1, 2, 3, 4, 5 };
int* ptr = &arr[0]; //int *ptr=arr;
for (int i = 0; i < 5; i++)
printf("%d ",ptr[i]); // printf("%d\n", *(ptr + i));
return 0;
}
8
Implementation of array using pointer
#include <stdio.h> // Print array elements using pointer
int main() printf("\nArray elements are:\n");
{ ptr = arr; // Reset pointer to the start of array
int n; for (int i = 0; i < n; i++)
printf("Enter the number of elements: "); {
scanf("%d", &n); printf("%d ", *(ptr+i)); // Equivalent to arr[i]
int arr[n]; // Declare an array with 'n' elements }
// Declare a pointer to traverse the array return 0;
int *ptr = arr; } // End of main()
// Read array elements using pointer
printf("Enter elements:\n");
for (int i = 0; i < n; i++)
{
scanf("%d", (ptr+i)); // Equivalent to &arr[i]
}
9
Implementation of array using pointer
#include <stdio.h> // Print array elements using pointer
int main() printf("\nArray elements are:\n");
{ ptr = arr; // Reset pointer to the start of the array
int n; for (int i = 0; i < n; i++)
printf("Enter the number of elements: "); {
scanf("%d", &n); printf("%d ", *ptr);
int arr[n]; // Declare an array with 'n' elements ptr++; // Move pointer to the next element
// Declare a pointer to traverse the array }
int *ptr = arr; return 0;
// Read array elements using pointer } // End of main()
printf("Enter elements:\n");
for (int i = 0; i < n; i++)
{
scanf("%d", ptr); // Use pointer to access each element
ptr++; // Move pointer to next element
}
10
int arr[n]; // Declare an array with 'n' elements
int *ptr = arr; // Declare a pointer to traverse the array
&arr[i] <= => ptr+i
arr[i] <= => *(ptr+i) <= => ptr[i]
11
#include <stdio.h>
int main()
Pointer and 2D Array
{
int a[3][4];
int (*p)[4]; printf("\nArray elements are:\n");
int i, j; for (i = 0; i < 3; i++)
p = a; {
printf("Enter elements of 2D array:\n"); for (j = 0; j < 4; j++)
for (i = 0; i < 3; i++) {
{ //printf("%d", a[i][j]);
for (j = 0; j < 4; j++) printf("%d ", *(*(p + i) + j));
{ }
//scanf("%d", &a[i][j]); printf("\n");
scanf("%d", (*(p + i) + j)); }
} return 0;
} }
12
#include <stdio.h>
int main()
{
Pointer and 2D Array
int a[2][3];
int (*p)[3]; // pointer to array of 3 integers
int i, j;
p = a; // p points to first row of the 2D array
printf("Enter elements of 2D array:\n");
for (i = 0; i < 2; i++)
{
for (j = 0; j < 3; j++)
{
scanf("%d", &p[i][j]); // pointer indexing
}
}
printf("\nArray elements are:\n");
for (i = 0; i < 2; i++)
{
for (j = 0; j < 3; j++)
{
printf("%d ", p[i][j]); // pointer indexing
}
printf("\n");
}
return 0;
} 13
To sort an array using pointers
#include <stdio.h>
// Function to sort the numbers using pointers
void sort(int n, int* ptr) {
int i, j, t; int main()
// Sort the numbers using pointers {
for (i = 0; i < n; i++) { int n = 5;
for (j = i + 1; j < n; j++) { int arr[] = { 0, 23, 14, 12, 9 };
if (*(ptr + j) < *(ptr + i)) { // arr[j] < arr[i]
t = *(ptr + i); // t = arr[i]; sort(n, arr);
*(ptr + i) = *(ptr + j); // arr[i] = arr[j]
*(ptr + j) = t; // arr[j] = t return 0;
} }
}
}
// print the numbers
for (i = 0; i < n; i++)
printf("%d ", *(ptr + i)); 14
}
Pass 1D Array to Functions in C
#include <stdio.h> #include <stdio.h>
// Passing Array as Pointer Notation // Passing Array as Pointer Notation
void printArr(int* arr, int n) { void printArr(int* arr) {
for (int i = 0; i < n; i++){ for (int i = 0; i < 5; i++){
printf("%d ", *arr); printf("%d ", *arr);
arr++; arr++;
} }
} }
int main() { int main() {
int arr[] = {1, 2, 3, 4, 5}; int arr[] = {1, 2, 3, 4, 5};
// Pass array to function // Pass array to function
printArr(arr, 5); printArr(arr);
return 0; return 0;
} }
15
Pass 2D Array to Functions in C
#include <stdio.h> int main()
{
void displayNumbers(int (*num)[3],int rows) int num[2][3];
{ printf("Enter 6 numbers:\n");
printf("Displaying:\n"); for (int i = 0; i < 2; ++i) {
for (int i = 0; i < rows; ++i) for (int j = 0; j < 3; ++j) {
{ scanf("%d", &num[i][j]); } }
for (int j = 0; j < 3; ++j) // pass multi-dimensional array to a function
{ displayNumbers(num, 2);
printf("%d\n", *(*(num+i)+j)); return 0;
} }
}
}
16
Pass 2D Array to Functions int main() {
int rows = 2, cols = 3;
int **num;
#include <stdio.h> /* Dynamic memory allocation */
#include <stdlib.h> num = (int **)malloc(rows * sizeof(int *));
for (int i = 0; i < rows; i++) {
void displayNumbers(int **num, int rows, int cols) num[i] = (int *)malloc(cols * sizeof(int));
{ }
printf("Displaying:\n"); printf("Enter 6 numbers:\n");
for (int i = 0; i < rows; i++) for (int i = 0; i < rows; i++) {
{ for (int j = 0; j < cols; j++) {
for (int j = 0; j < cols; j++) scanf("%d", &num[i][j]);
{ }
printf("%d\n", *(*(num + i) + j)); }
} displayNumbers(num, rows, cols);
} /* Free allocated memory */
} for (int i = 0; i < rows; i++) {
free(num[i]);
}
free(num);
return 0;
} 17
Pointer Arithmetic
• Pointer Arithmetic is the set of valid arithmetic operations that can be
performed on pointers.
• Increment/Decrement of a Pointer
• Addition of integer to a pointer
• Subtraction of integer to a pointer
• Subtracting two pointers of the same type
• Comparison of pointers
18
Increment/Decrement of a Pointer
• When a pointer is incremented, it actually increments by the number
equal to the size of the data type for which it is a pointer.
• When a pointer is decremented, it actually decrements by the
number equal to the size of the data type for which it is a pointer.
int a = 22;
int *p = &a;
printf("p = %u\n", p); // p = 6422288
p++;
printf("p++ = %u\n", p); //p++ = 6422292 (+4 bytes)
p--;
printf("p-- = %u\n", p);
19
Addition of Integer to Pointer
• When a pointer is added with an integer value, the value is first
multiplied by the size of the data type and then added to the pointer.
int N = 4;
int *ptr;
ptr = &N;
printf("Pointer ptr before Addition: ");
printf("%p \n", ptr);
ptr = ptr + 3;
printf("Pointer ptr after Addition: ");
printf("%p \n", ptr);
20
Subtraction of Integer from Pointer
• When a pointer is subtracted with an integer value, the value is first
multiplied by the size of the data type and then subtracted from the
pointer.
int N = 4;
int *ptr;
ptr = &N;
printf("Pointer ptr before Addition: ");
printf("%p \n", ptr);
ptr = ptr-2;
printf("Pointer ptr after Addition: ");
printf("%p \n", ptr);
21
Subtraction of Two Pointers
• The subtraction of two pointers is possible only when they have the same data
type.
• The result is generated by calculating the difference between the addresses of
the two pointers and calculating how many bits of data it is according to the
pointer data type.
int main(){
int a[]= {10, 20, 30, 40, 50, 60, 70, 80, 90, 100};
int *x = &a[0]; // zeroth element
int *y = &a[9]; // last element
printf("Addr of a[0]: %ld\n Addr of a[9]: %ld\n", x, y);
printf("Subtraction of two pointers: %ld", y-x);
}
22
Comparison of pointers
#include <stdio.h>
/* Comparing pointer with itself */
int main()
if (p1 == p1)
{ printf("p1 and p1 are equal\n");
int a = 10, b = 20; /* Comparing pointer with NULL */
if (p2 != NULL)
int arr[5] = {10, 20, 30, 40, 50};
printf("p2 is not NULL\n");
int *p1 = &a; return 0;
int *p2 = &b; }
int *p3 = &arr[1];
int *p4 = &arr[3];
/* Comparing pointers pointing to SAME array */
if (p3 < p4)
printf("p3 points to a lower address than p4\n");
if (p4 > p3)
printf("p4 points to a higher address than p3\n"); 23
Dynamic Memory Allocation
• A procedure in which the size of a data structure (like Array) is
changed during the runtime.
• Defined under <stdlib.h> header file
• malloc()
• calloc()
• free()
• realloc()
24
malloc()
• The malloc() function reserves a block of memory of the specified
number of bytes.
• It returns a pointer of void which can be casted into pointers of any
form.
• ptr = (castType *) malloc(size);
• The expression results in a NULL pointer if the memory cannot be
allocated.
25
// Program to calculate the sum of n numbers entered by the user
#include <stdio.h>
#include <stdlib.h>
int main() {
int n, i, *ptr, sum = 0;
printf("Enter number of elements: ");
scanf("%d", &n);
ptr = (int*) malloc(n * sizeof(int));
// if memory cannot be allocated
if(ptr == NULL) { printf("Error! memory not allocated."); exit(0); }
printf("Enter elements: ");
for(i = 0; i < n; ++i) {
scanf("%d", ptr + i);
sum += *(ptr + i);
}
printf("Sum = %d", sum);
// deallocating the memory
free(ptr);
return 0;
} 26
#include <stdio.h> Expression Meaning // Read integers
arr[i] Value at index i printf("Enter %d integers:\n", n);
#include <stdlib.h>
&arr[i] Address of index i for (i = 0; i < n; i++) {
int main() { //scanf("%d", &arr[i]);
arr + i Address of index i
int n, i; *(arr + i) Value at index i scanf("%d",arr+i);
int *arr; }
// Display integers
printf("Enter number of integers: ");
printf("You entered:\n");
scanf("%d", &n); for (i = 0; i < n; i++) {
// Dynamic memory allocation //printf("%d ", arr[i]);
arr = (int *)malloc(n * sizeof(int)); printf("%d ",*(arr+i));
}
// Check if memory allocation is successful
// Free allocated memory
if (arr == NULL) { free(arr);
printf("Memory allocation failed!\n"); return 0;
return 1; }
} 27
Static memory allocation
int arr[n]; // Declare an array with 'n' elements
int *ptr = arr; // Declare a pointer to traverse the array
&arr[i] <= => ptr+i --------------------------------Address of index i
arr[i] <= => *(ptr+i) <= => ptr[i] ----------Value at index i
Dynamic memory allocation
int *arr;
arr = (int *)malloc(n * sizeof(int));
&arr[i]) <= => arr+i ------Address of index i
arr[i]) <= => *(arr+i) ---Value at index i
28
calloc()
• “calloc” or “contiguous allocation” method in C is used to dynamically
allocate the specified number of blocks of memory of the specified
type. it is very much similar to malloc() but has two different points
and these are:
• It initializes each block with a default value ‘0’.
• It has two parameters or arguments as compare to malloc().
• ptr = (cast-type*)calloc(n, element-size);
• here, n is the no. of elements and element-size is the size of each
element.
29
// Program to calculate the sum of n numbers entered by the user
#include <stdio.h>
#include <stdlib.h>
int main() {
int n, i, *ptr, sum = 0;
printf("Enter number of elements: ");
scanf("%d", &n);
ptr = (int*) calloc(n, sizeof(int));
if(ptr == NULL) { printf("Error! memory not allocated."); exit(0); }
printf("Enter elements: ");
for(i = 0; i < n; ++i) {
scanf("%d", ptr + i);
sum += *(ptr + i);
}
printf("Sum = %d", sum);
free(ptr);
return 0;} 30
realloc()
• “realloc” or “re-allocation” method in C is used to dynamically change
the memory allocation of a previously allocated memory.
• If the memory previously allocated with the help of malloc or calloc is
insufficient, realloc can be used to dynamically re-allocate memory.
• Re-allocation of memory maintains the already present value and
new blocks will be initialized with the default garbage value.
• ptr = realloc(ptr, newSize);
where ptr is reallocated with new size 'newSize'.
31
#include <stdio.h>
#include <stdlib.h>
int main() {
int *ptr, i , n1, n2;
printf("Enter size: ");
scanf("%d", &n1);
ptr = (int*) malloc(n1 * sizeof(int));
printf("Addresses of previously allocated memory:\n");
for(i = 0; i < n1; ++i)
printf("%p\n",ptr + i);
printf("\nEnter the new size: ");
scanf("%d", &n2);
ptr = realloc(ptr, n2 * sizeof(int));
printf("Addresses of newly allocated memory:\n");
for(i = 0; i < n2; ++i)
printf("%p\n", ptr + i);
free(ptr);
return 0;
}
32
free()
• “free” method in C is used to dynamically de-allocate the memory.
• The memory allocated using functions malloc() and calloc() is not de-
allocated on their own.
• Hence the free() method is used, whenever the dynamic memory
allocation takes place.
• free(ptr);
33
Function Pointer
• A function pointer is a type of pointer that stores the address of a
function, allowing functions to be passed as arguments and invoked
dynamically.
• Syntax return_type (*pointer_name)(parameter_types);
34
int main() {
#include <stdio.h>
int (*fptr)(int);
int increment(int a) { // Assign to increment()
return ++a; fptr = &increment;
// Call the function via ptr
} int result=fptr(10);
int decrement(int a) { printf("%d\n", result);
return --a;
fptr = &decrement;
} // Call the function via ptr
result=fptr(10);
printf("%d", result);
return 0;
} 35
Function as an argument
#include <stdio.h>
int increment(int a) {
return ++a;
}
int decrement(int a) {
return --a;
}
void update(int a, int (*op)(int)) {
printf("%d\n", op(a));
}
int main() {
update(10, increment);
update(20, decrement);
return 0;
}
36