Types of Pointer in Programming (original) (raw)
Pointers in programming are variables that store the memory address of another variable. There are several types of pointers, including **Null pointer, **Void pointer, **Wild pointer, **Dangling pointer, **Complex pointer, **Near pointer, **Far pointer, and **Huge pointer. Each type has its characteristics and uses, providing flexibility and efficiency in **memory management.
What is a Pointer?
A variable that stores another variable's memory address is called a pointer. Normal variables store values. But pointers hold memory locations where values are kept. Using pointers lets you access and change system memory directly. This can make programs more efficient and powerful. C and C++ use pointers a lot. But other languages can also have pointers, though maybe not the same.
Types of Pointers in Programming:
There are several types of pointers used in programming, each serving different purposes:
**1. Basic Pointer:
A **primary pointer is a **variable that is a memory address of another variable. Instead of having the data itself physically present, pointers only connect to the memory location where the data is kept. Answering that, the program will get a chance to use it to read and write with the value located at the given **memory address.
Below is the implementation of the above idea:
C++ `
#include using namespace std;
int main() { // Declare an integer variable int var = 23; // Declare a pointer to an integer int* ptr; // Assign the pointer the address of var ptr = &var;
cout << "Value of var: " << var << endl;
cout << "Address of var: " << &var << endl;
cout << "Value of ptr (Address it holds): " << ptr
<< endl;
cout << "Value pointed to by ptr: " << *ptr
<< endl; // Dereferencing pointer to access the
// value of var
return 0;
}
C
#include <stdio.h>
int main() { int var = 23;
// Declare a pointer to an integer
int* ptr;
// Assign the pointer the address of var
ptr = &var;
// Output the value of var
printf("Value of var: %d\n", var);
// Output the memory address of var
printf("Address of var: %p\n", &var);
// Output the address stored in ptr
printf("Value of ptr (Address it holds): %p\n", ptr);
// Output the value at the memory address stored in ptr
printf("Value pointed to by ptr: %d\n", *ptr);
return 0;
}
`
Output
Value of var: 23 Address of var: 0x7ffc833c13b4 Value of ptr (Address it holds): 0x7ffc833c13b4 Value pointed to by ptr: 23
**2. Null Pointer:
Null pointer is a specific component of pointers which doesn’t point to any **legitimate memory location. It is applied in programming to denote the particular case when a pointer intentionally not points on an object and is **uninitialized. Such a pointer absolutely literally refers to the value **0 (or **NULL, which in C terminology is generally set to **0, and **nullptr in C++), which denotes a protected value reserved by the language rules that does not refer to anything.
Below is the implementation of the above idea:
C++ `
#include using namespace std;
int main() { int *ptr = nullptr; // Preferred over NULL in C++
if (ptr == nullptr) {
cout << "The pointer is null." << endl;
}
return 0;
}
C
#include <stdio.h>
int main() { int *ptr = NULL; // Declaration of a null pointer
if (ptr == NULL) {
printf("The pointer is null.\n");
}
return 0;
}
Java
public class Main { public static void main(String[] args) { Integer num = null; // Java uses null to denote the absence of a value.
if (num == null) {
System.out.println("The variable is null.");
}
}
}
Python
num = None # Python's equivalent to null pointers in other languages
if num is None: print("The variable is None.")
JavaScript
// In JavaScript, we use 'let' to declare variables let ptr = null;
// 'if' statement is used to check if the pointer is null if (ptr === null) { // 'console.log' is used in JavaScript for printing console.log("The pointer is null."); }
`
Output
The pointer is null.
**3. Pointer to Pointer (Double Pointer):
Pointer to a pointer sometimes gets referred as a **double pointer. It is a type of pointer which stores the memory address of another pointer. Double pointers are used to achieve indirect reference of data via another pointer in the case of its required. As an important point, this C-like languages features support multiple indirection that can be used as extra layers to direct data structures which are the most useful for the **dynamic data structures.
Below is the implementation of the above idea:
C++ `
//Passing Pointers to Functions
#include using namespace std;
void allocateArray(int** &ptr, int size) { ptr = new int*[size]; // Allocate array of pointers for (int i = 0; i < size; i++) { ptr[i] = new int[size]; // Allocate int array for each pointer }
// Initialize array elements
int value = 1;
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
ptr[i][j] = value++;
}
}
}
void freeArray(int** &ptr, int size) { for (int i = 0; i < size; i++) { delete[] ptr[i]; // Free each sub-array } delete[] ptr; // Free the top-level array ptr = nullptr; // Safeguard pointer }
int main() { int **arr = nullptr; int size = 3;
allocateArray(arr, size);
// Output the array
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
cout << arr[i][j] << " ";
}
cout << endl;
}
freeArray(arr, size);
return 0;
}
C
//Dynamic 2D Array to show working of Double pointers in C.
#include <stdio.h> #include <stdlib.h>
int main() { int **arr; // Declare a double pointer int rows = 3; int cols = 4; int i, j, count = 0;
// Step 1: Allocate memory for 'rows' pointers
arr = (int **)malloc(rows * sizeof(int *));
if (arr == NULL) {
fprintf(stderr, "Out of memory\n");
exit(1);
}
// Step 2: Allocate memory for each row
for (i = 0; i < rows; i++) {
arr[i] = (int *)malloc(cols * sizeof(int));
if (arr[i] == NULL) {
fprintf(stderr, "Out of memory\n");
exit(1);
}
}
// Step 3: Assign values to allocated memory
for (i = 0; i < rows; i++) {
for (j = 0; j < cols; j++) {
arr[i][j] = ++count; // Or any other value
}
}
// Step 4: Output the array
for (i = 0; i < rows; i++) {
for (j = 0; j < cols; j++) {
printf("%d ", arr[i][j]);
}
printf("\n");
}
// Step 5: Free the allocated memory
for (i = 0; i < rows; i++) {
free(arr[i]);
}
free(arr);
return 0;
}
`
**4. Smart Pointers:
Smart pointers are advanced cursor varieties provided by C++ to look after the memory of the dynamically allocated objects. They are STL(C++ Standard Library) **generic classes that contain a plain pointer and ensure the code is not brought up in memory leaks and dangling pointers and, therefore, is clean and elegant. Smart pointers act as **automatic memory deallocators, simulating the works of regular pointer with additional logics to manage lifecycle and resources, but eventually introduce a safer approach to overcome the problem mentioned with using traditional **raw pointers.
Below is the implementation of the above idea:
C++ `
#include #include // Include for smart pointers using namespace std;
int main() { // Using std::unique_ptr unique_ptr uPtr(new int(10)); cout << "uPtr = " << *uPtr << endl;
// Transferring ownership
unique_ptr<int> uPtr2 = move(uPtr);
if (!uPtr)
std::cout << "uPtr is empty\n";
// Using std::shared_ptr
shared_ptr<int> sPtr(new int(20));
shared_ptr<int> sPtr2 = sPtr; // Both now own the memory
cout << "sPtr = " << *sPtr << ", sPtr2 = " << *sPtr2
<< endl;
cout << "sPtr use_count = " << sPtr.use_count() << endl;
// Using std::weak_ptr
weak_ptr<int> wPtr(
sPtr); // Does not increase reference count
shared_ptr<int> sPtr3
= wPtr.lock(); // Creates a shared_ptr from weak_ptr
if (sPtr3)
cout << "sPtr3 = " << *sPtr3 << endl;
return 0;
}
`
Output
uPtr = 10 uPtr is empty sPtr = 20, sPtr2 = 20 sPtr use_count = 2 sPtr3 = 20
5. Void Pointers:
A void pointer in programming is a special type of pointer that doesn’t have an associated data type. It can hold the address of any type of data and can be typecasted to any type. This makes it a versatile tool, often referred to as a “generic pointer” or "**wildcard pointer", used in various programming scenarios for **flexibility and **efficiency.
- Void Pointers can hold the address of a data type of **integer, a **float or a **string, even to structured data.
- Does not figure out which type of **object it is pointing at and thus is unable to be directly **deference.
- A **reference to it needs to be casted as **another pointer type before it can be **dereferenced.
- Generally available in C for **dynamic memory allocation, interfacing with the hardware, implementing polymorphic functions, and handling the data in the constructs which are agnostic to the data types.
Below is the implementation of the above idea:
C++ `
#include using namespace std;
int main() { int a = 10; float b = 3.14; void *p = nullptr; // using nullptr which is type-safe in C++
p = &a;
cout << "Integer value: " << *(static_cast<int*>(p)) << endl; // using static_cast for type safety
p = &b;
cout << "Float value: " << *(static_cast<float*>(p)) << endl;
return 0;
}
C
#include <stdio.h> #include <stdlib.h>
int main() { int a = 10; float b = 3.14; void *p = NULL; // void pointer declaration
p = &a; // storing address of int
printf("Integer value: %d\n", *(int *)p); // type casting to int pointer and dereferencing
p = &b; // storing address of float
printf("Float value: %f\n", *(float *)p); // type casting to float pointer and dereferencing
return 0;
}
`
Output
Integer value: 10 Float value: 3.14
6. Integer Pointer:
Integer pointer is a kind of pointer that when it points it does so specifically to integer. Pointers stores the RAM address of another variable while they are the variables themselves. In the case of pointers to integers the address or the place that the value of integer is located will be implicated.
Below is the implementation of the above idea:
C++ `
#include using namespace std;
int main() { int val = 10; int* ptr = &val;
cout << "Value of val: " << val << endl;
cout << "Address of val: " << &val << endl;
cout << "Value of ptr: " << ptr << endl;
cout << "Value pointed to by ptr: " << *ptr << endl;
return 0;
}
C
#include <stdio.h>
int main() { int val = 10; int *ptr = &val; // Pointer to an integer variable
printf("Value of val: %d\n", val); // Output the value of val
printf("Address of val: %p\n", (void *)&val); // Output the memory address of val
printf("Value of ptr: %p\n", (void *)ptr); // Output the memory address stored in ptr
printf("Value pointed to by ptr: %d\n", *ptr); // Output the value at the memory address stored in ptr
return 0;
}
`
Output
Value of val: 10 Address of val: 0x7ffe482d9c74 Value of ptr: 0x7ffe482d9c74 Value pointed to by ptr: 10
7. Float Pointer:
A float pointer is a pointer that specifically refers to the address of a floating-point data type. The floating-point data type usually represents real numbers (numbers with fractional parts) in the way that a single representation can accommodate a large range of values. The pointer keeps the memory address where the first byte of the float data type is remained. Pointers, in general, are applicable for efficient accessing of arrays and other data structures, dynamic memory administration and handling polymorphism in object-oriented programming language. Procedural languages that have float pointers.
Below is the implementation of the above idea:
C `
#include <stdio.h>
int main() { float number = 10.5; float* ptr = &number; // Pointer to a float
printf("Value of number: %f\n", number);
printf("Address of number: %p\n", (void*)&number);
printf("Value of ptr (address it points to): %p\n", (void*)ptr);
printf("Value at address stored in ptr: %f\n", *ptr);
return 0;
}
`
Output
Value of number: 10.500000 Address of number: 0x7fff573317ec Value of ptr (address it points to): 0x7fff573317ec Value at address stored in ptr: 10.500000
8. Array Pointers:
An array pointer is a kind of pointer that can be used to point to the first element of the associated array in the memory. Such a pointer, besides storing the memory address of the fist element of the array, is also usually tied to the element type of the array. The pointer will become aware of this and will facilitate pointer arithmetic making it possible to either increase it or decrease it and move through the array.
Array pointer can be defined as:
- A pointer that indicates the location of the first item of an array.
- It is applicable for random access of the array elements by using the pointer instead of the array indices.
Below is the implementation of the above idea:
C `
#include <stdio.h>
int main() { int arr[] = {10, 20, 30, 40, 50}; int* p = arr; // Array pointer to the first element of arr
for(int i = 0; i < 5; i++) {
printf("%d ", *(p + i)); // Accessing array elements through pointer arithmetic
}
return 0;
}
C#
using System;
class Program { static unsafe void Main() { int[] arr = {10, 20, 30, 40, 50}; fixed (int* p = arr) { for(int i = 0; i < arr.Length; i++) { Console.WriteLine(*(p + i)); // Pointer arithmetic to navigate through the array } } } }
`
9. Function Pointer:
Function pointers are very powerful programming tools using which programmers can save function references that can be later called. It is the feature that is most visible for callback functions, implementing plugins, or for the simulation of polymorphism in C-like languages. Here is a short description of function pointers and their use in the several programming languages that allow this functionality.
Below is the implementation of the above idea:
C++ `
#include using namespace std;
class Base { public: void say_hello() const { cout << "Hello, World!\n"; } };
int main() { void (Base::*func_ptr)() const = &Base::say_hello; Base obj; (obj.*func_ptr)(); // Calling member function using function pointer return 0; }
C
#include <stdio.h>
void hello() { printf("Hello, World!\n"); }
void goodbye() { printf("Goodbye, World!\n"); }
int main() { void (*func_ptr)(); // Declaration of a function pointer func_ptr = hello; // Pointing to hello function func_ptr(); // Calling hello function func_ptr = goodbye; // Now pointing to goodbye function func_ptr(); // Calling goodbye function return 0; }
C#
using System;
public delegate void GreetingDelegate();
public class Program { public static void SayHello() { Console.WriteLine("Hello, World!"); }
public static void Main() {
GreetingDelegate del = new GreetingDelegate(SayHello);
del();
}
}
`
10. Pointer to Structure (Struct Pointer):
A Pointer to Structure (or Struct Pointer) is a concept present in some programming languages C and C++. This construct enables a creation of pointers purposely directed to structures. Different from Structures, these structures are user-specified data types that permit the combination of different items of data. Pointer to structures are especially important for dynamic allocation of memory, function parameters passed to big structures with less overhead, and data structures which include linked lists and trees.
A struct pointer in programming is a type of pointer that remembers the address of a structure. The struct pointer is used instead of the usual numeric data type. It refers to a struct data type which is user-defined.
Below is the implementation of the above idea:
C++ `
#include #include using namespace std;
struct Employee { int id; char name[20]; };
int main() { Employee *ptr = new Employee; // Dynamically allocate memory for one Employee struct
// Access struct members through pointer
ptr->id = 123;
strcpy(ptr->name, "Geeks For Geeks");
cout << "Employee ID: " << ptr->id << endl;
cout << "Employee Name: " << ptr->name << endl;
delete ptr; // Free the allocated memory
return 0;
}
C
#include <stdio.h> #include <stdlib.h>
typedef struct { int id; char name[20]; } Employee;
int main() { Employee *ptr = malloc(sizeof(Employee)); // Dynamically allocate memory for one Employee struct if (ptr == NULL) { fprintf(stderr, "Malloc failed\n"); return -1; }
// Accessing struct members through pointer using arrow operator
ptr->id = 123;
strcpy(ptr->name, "Geeks For Geeks");
printf("Employee ID: %d\n", ptr->id);
printf("Employee Name: %s\n", ptr->name);
free(ptr); // Free the allocated memory
return 0;
}
`
Output
Employee ID: 123 Employee Name: Geeks For Geeks
Conclusion:
In conclusion, pointers in programming are powerful tools that hold memory addresses of variables. Different types of pointers like Null, Void, Wild, Dangling, Complex, Near, Far, and Huge pointers each have unique properties and uses. They play a crucial role in memory management, making programs more efficient and flexible.