Application of pointer in C++
In this article, we will discuss the application of pointers in C++. But before discussing the applications of pointers, we must know about the pointers in C++.
What are pointers?
Pointers are strong and adaptable C++ building blocks that are essential to many programming tasks. A variable called a pointer that is used to store another variable's memory address. This feature makes it possible to apply complex data structures, manipulate data effectively, and allocate memory dynamically.
There are several applications of the pointer. Some main applications of the pointer are as follows:
Dynamic Memory Allocation:
The ability for programs to allocate memory at runtime is made possible by pointers, which enable dynamic memory allocation. The dynamically allocated memory address is stored in pointers, while the heap is allocated using the new operator. It is very helpful when working with unknown-size data structures or when the size could change while the program is running.
int *dynamicArray = new int[15];
Function pointers:
Function pointers are supported by C++ and enable the allocation of functions to variables as well as the passing of functions as arguments to other functions. It is particularly helpful when there are situations where different functions must be called depending on specific criteria.
int add(int x, int y) {
return x + y;
}
int subtract(int x, int y) {
return x - y;
}
int (*operation)(int, int);
operation = add;
Pointers and Arrays:
In C++, pointers and arrays are closely connected to each other. A pointer to the array's first element is all that an array name is. Pointers can be utilized to efficiently navigate through the elements of an array.
int numbers[] = {1, 2, 3, 4, 5};
int *ptr = numbers;
Arithmetic Pointers:
Pointers make access to data structures and arrays efficiently available, enabling arithmetic operations such as addition and subtraction. It is very helpful when looking over each element of a memory block one by one.
int numbers[] = {1, 2, 3, 4, 5};
int *ptr = numbers;
ptr++; // Move to the next element from the array
Dynamic Data Structures:
Pointers are essential when creating dynamic data structures like trees, graphs, and linked lists. During program execution, these structures may expand or contract, and pointers make it easier to dynamically allocate and de-allocate memory.
struct Node {
int data;
Node* next;
};
Node* head = new Node;
Example:
Let us take an example to illustrate the use of pointers in C++.
#include <iostream>
// Struct for linked list node
struct Node {
int data;
Node* next;
};
int main() {
// Dynamic Memory Allocation for an array
int arraySize;
std::cout << "Enter the size of the array: ";
std::cin >> arraySize;
int *dynamicArray = new int[arraySize];
// Initialize the array elements
for (int i = 0; i < arraySize; ++i) {
dynamicArray[i] = i * 2;
}
// Pointers and Arrays - Iterate through the array
std::cout << "Array elements: ";
for (int i = 0; i < arraySize; ++i) {
std::cout << dynamicArray[i] << " ";
}
std::cout << std::endl;
// Dynamic Data Structures (Linked List)
Node* head = nullptr;
Node* current = nullptr;
// Create a linked list with elements from the array
for (int i = 0; i < arraySize; ++i) {
Node* newNode = new Node;
newNode->data = dynamicArray[i];
newNode->next = nullptr;
if (head == nullptr) {
head = newNode;
current = head;
} else {
current->next = newNode;
current = newNode;
}
}
// Display the linked list
std::cout << "Linked List elements: ";
Node* currentNode = head;
while (currentNode != nullptr) {
std::cout << currentNode->data << " ";
currentNode = currentNode->next;
}
std::cout << std::endl;
// Cleanup dynamic memory
delete[] dynamicArray;
// Cleanup linked list
currentNode = head;
while (currentNode != nullptr) {
Node* nextNode = currentNode->next;
delete currentNode;
currentNode = nextNode;
}
return 0;
}
Output:
Enter the size of the array: 5
Array elements: 0 2 4 6 8
Linked List elements: 0 2 4 6 8
Enter the size of the array: 10
Array elements: 0 2 4 6 8 10 12 14 16 18
Linked List elements: 0 2 4 6 8 10 12 14 16 18
Example 2:
Let us take an example to illustrate the use of pointers in C++.
#include <iostream>
using namespace std;
int main () {
int var = 15; // actual variable declaration.
int *ip; // pointer variable
ip = &var; // store address of var in pointer variable
cout << "Value of var variable: ";
cout << var << endl;
// print the address stored in ip pointer variable present in the program
cout << "Address stored in ip variable: ";
cout << ip << endl;
// access the value at the address available in pointer
cout << "Value of *ip variable: ";
cout << *ip << endl;
return 0;
}
Output:
Value of var variable: 15
Address stored in ip variable: 0x7ffe0b946344
Value of *ip variable: 15
Example 3:
#include <iostream>
#include <string>
// Structure representing a student
struct Student {
std::string name;
int grade;
};
// Function prototypes
void displayStudent(const Student* student);
void incrementGrade(Student* student);
int main() {
const int numStudents = 3;
// Dynamic Memory Allocation for an array of students
Student* studentArray = new Student[numStudents];
// Initialize the array of students
studentArray[0] = { "Alice", 90 };
studentArray[1] = { "Bob", 85 };
studentArray[2] = { "Charlie", 95 };
// Pointers and Arrays - Iterate through the array using pointer arithmetic
std::cout << "Student Information:" << std::endl;
for (int i = 0; i < numStudents; ++i) {
displayStudent(&studentArray[i]);
}
// Function Pointers - Increment the grades using a function pointer
void (*gradeUpdater)(Student*);
gradeUpdater = incrementGrade;
for (int i = 0; i < numStudents; ++i) {
gradeUpdater(&studentArray[i]);
}
// Display updated student information
std::cout << "\nUpdated Student Information:" << std::endl;
for (int i = 0; i < numStudents; ++i) {
displayStudent(&studentArray[i]);
}
// Cleanup dynamic memory
delete[] studentArray;
return 0;
}
// Function definitions
void displayStudent(const Student* student) {
std::cout << "Name: " << student->name << ", Grade: " << student->grade << std::endl;
}
void incrementGrade(Student* student) {
// Increment the student's grade
student->grade += 5;
}
Output:
Student Information:
Name: Alice, Grade: 90
Name: Bob, Grade: 85
Name: Charlie, Grade: 95
Updated Student Information:
Name: Alice, Grade: 95
Name: Bob, Grade: 90
Name: Charlie, Grade: 100
Example 4:
#include <iostream>
// Node structure for the linked list
struct Node {
int data;
Node* next;
};
// Function prototypes
Node* createNode(int data);
void insertNode(Node*& head, int data);
void displayList(const Node* head);
void deleteList(Node*& head);
int main() {
// Create an empty linked list
Node* linkedList = nullptr;
// Insert nodes into the linked list
insertNode(linkedList, 9);
insertNode(linkedList, 30);
insertNode(linkedList, 39);
insertNode(linkedList, 48);
insertNode(linkedList, 60);
// Display the linked list
std::cout << "Linked List Elements: ";
displayList(linkedList);
// Cleanup the linked list
deleteList(linkedList);
return 0;
}
// Function to create a new node
Node* createNode(int data) {
Node* newNode = new Node;
newNode->data = data;
newNode->next = nullptr;
return newNode;
}
// Function to insert a node at the end of the linked list
void insertNode(Node*& head, int data) {
if (head == nullptr) {
head = createNode(data);
} else {
Node* current = head;
while (current->next != nullptr) {
current = current->next;
}
current->next = createNode(data);
}
}
// Function to display the elements of the linked list
void displayList(const Node* head) {
const Node* current = head;
while (current != nullptr) {
std::cout << current->data << " ";
current = current->next;
}
std::cout << std::endl;
}
// Function to delete the entire linked list and free memory
void deleteList(Node*& head) {
while (head != nullptr) {
Node* temp = head;
head = head->next;
delete temp;
}
}
Output:
Linked List Elements: 9 30 39 48 60
Example 5:
#include <iostream>
// Function prototypes
int* createDynamicArray(int size);
void initializeArray(int* arr, int size);
void displayArray(const int* arr, int size);
void incrementArrayValues(int* arr, int size);
void deleteDynamicArray(int* arr);
int main() {
// Create a dynamic array of size 5
int arraySize = 10;
int* dynamicArray = createDynamicArray(arraySize);
// Initialize and display the array
initializeArray(dynamicArray, arraySize);
std::cout << "Initial Array: ";
displayArray(dynamicArray, arraySize);
// Increment values in the array
incrementArrayValues(dynamicArray, arraySize);
std::cout << "Array after incrementing values: ";
displayArray(dynamicArray, arraySize);
// Cleanup dynamic memory
deleteDynamicArray(dynamicArray);
return 0;
}
// Function to dynamically create an integer array
int* createDynamicArray(int size) {
return new int[size];
}
// Function to initialize elements of the array
void initializeArray(int* arr, int size) {
for (int i = 0; i < size; ++i) {
arr[i] = i + 1;
}
}
// Function to display the elements of the array
void displayArray(const int* arr, int size) {
for (int i = 0; i < size; ++i) {
std::cout << arr[i] << " ";
}
std::cout << std::endl;
}
// Function to increment each element of the array
void incrementArrayValues(int* arr, int size) {
for (int i = 0; i < size; ++i) {
arr[i] += 5;
}
}
// Function to release memory allocated for the dynamic array
void deleteDynamicArray(int* arr) {
delete[] arr;
}
Output:
Initial Array: 1 2 3 4 5 6 7 8 9 10
Array after incrementing values: 6 7 8 9 10 11 12 13 14 15
Conclusion:
Pointers are an important and useful tool in C++ programming because they provide a strong mechanism for dynamic memory allocation, effective data manipulation, and the creation of complex data structures. They make it possible to create dynamic arrays, make it easier to navigate through arrays and structures and create complex data structures like graphs, linked lists, and trees. By enabling functions to be assigned to variables and passed as arguments, function pointers offer flexibility and help write more modular and adaptive code. Creating and managing dynamic memory gives you flexibility in handling different data sizes during program execution, and pointer arithmetic makes traversing data structures efficient.