Loading...

Pointers and Arrays in C++

Pointers and Arrays in C++

Introduction

Pointers, arrays, and arithmetic pointers are fundamental concepts in programming, especially in languages like C and C++. Understanding their relationship is crucial for writing efficient and flexible code. In this article, we'll delve into the connections between pointers, arrays, and arithmetic pointers, exploring how they interact and contribute to the functionality of programs.

Pointer

A pointer in programming is a variable that holds the memory address of another variable. Instead of directly storing data, a pointer stores the address of the location where the data is stored in memory. This allows for indirect access to the data, enabling dynamic memory allocation, manipulation of complex data structures, and efficient passing parameters in functions.

It points to the location in memory where the data is stored.

int *ptr; // Declares a pointer to an integer

This declares a pointer variable ptr that can store the memory address of an integer variable. Once declared, a pointer can be assigned the address of another variable using the address-of operator (&) or by assigning it directly if the variable is already a pointer.

int num = 10;
int *ptr = # // Assigns the address of num to ptr

Now, ptr contains the memory address of the variable num. We can access the value stored at that address using the dereference operator (*).

printf("%d", *ptr); // Prints the value of num (10)

Array

An array is a data structure that stores a collection of elements of the same data type in contiguous memory locations. Each element in the array can be accessed by its index, which represents its position in the array.

#include <iostream>

int main() {
    // Declaring an array of integers with 5 elements
    int arr[5];

    // Initializing the array with values
    arr[0] = 10;
    arr[1] = 20;
    arr[2] = 30;
    arr[3] = 40;
    arr[4] = 50;

    // Accessing and printing elements of the array
    std::cout << "Elements of the array:" << std::endl;
    for (int i = 0; i < 5; ++i) {
        std::cout << "arr[" << i << "] = " << arr[i] << std::endl;
    }

    return 0;
}

In this illustration:

  1. We declare an array named arr of integers with a size of 5 elements: int arr[5];.
  2. We initialize the elements of the array with values using array indexing: arr[0] = 10;, arr[1] = 20;, and so on.
  3. We then access and print each element of the array using a for loop, iterating over the indices from 0 to 4.
  4. The output displays each element of the array along with its index.

Output:

Elements of the array:
arr[0] = 10
arr[1] = 20
arr[2] = 30
arr[3] = 40
arr[4] = 50

Pointers and Arrays

In C and C++, arrays and pointers are closely related. In fact, arrays are essentially a contiguous block of memory, with each element occupying a specific memory location. When you declare an array, you are essentially creating a pointer to the first element of that array.

For example:

int arr[5] = {1, 2, 3, 4, 5};
int *ptr = arr; // ptr points to the first element of arr

In this example, ptr points to the first element of the array arr. This is possible because the name of the array arr itself acts as a pointer to its first element.

Accessing Array Elements using Pointers

Array elements can be accessed using pointers. When an array name is used in an expression, it decays into a pointer to its first element. This allows us to use pointer arithmetic to access other elements of the array.

Suppose we need to point to the 3rd element of the array using the pointer.

As, we all know that ptr in above example points to the first element of the array, then ptr + 2 will point to the third element.

For example:

int arr[5];
int *ptr;

ptr = arr; // here we didnt used & because arr itself is a pointer
this is equivalent to &arr[0]

*(ptr)     is equivalent to arr[0]
*(ptr + 1) is equivalent to arr[1]
*(ptr + 2) is equivalent to arr[2]
*(ptr + 3) is equivalent to arr[3]
*(ptr + 4) is equivalent to arr[4]
#include <iostream>

int main() {
    int arr[5] = {10, 20, 30, 40, 50};
    int *ptr = arr; // Pointer points to the first element of the array

    // Accessing array elements using pointers
    std::cout << "Array elements using pointers:" << std::endl;
    for (int i = 0; i < 5; ++i) {
        std::cout << "Element " << i << ": " << *(ptr + i) << std::endl;
    }

    return 0;
}

Output:

Array elements using pointers:
Element 0: 10
Element 1: 20
Element 2: 30
Element 3: 40
Element 4: 50

Pointer Arithmetic for Array Traversal

Pointer arithmetic can be used to traverse through array elements efficiently. By incrementing or decrementing the pointer, we can navigate to the next or previous element in the array.

#include <iostream>

int main() {
    int arr[5] = {10, 20, 30, 40, 50};
    int *ptr = arr; // Pointer points to the first element of the array

    // Traverse array elements using pointer arithmetic
    std::cout << "Array elements using pointer arithmetic:" << std::endl;
    for (int i = 0; i < 5; ++i) {
        std::cout << "Element " << i << ": " << *ptr << std::endl;
        ptr++; // Move pointer to the next element
    }

    return 0;
}

Output:

Array elements using pointer arithmetic:
Element 0: 10
Element 1: 20
Element 2: 30
Element 3: 40
Element 4: 50

Printing Addresses

Address can be print through different ways:

In Arrays:

  1. (array + i)
  2. i[array]

 

Mitigate Confusion

Arrays and pointers have a close relationship but they are not exactly the same thing.

let's find out the concept of three statements:

int *ptr;
int arr[5] = {1, 2, 3, 4, 5};

1) ptr = arr;
2) ptr = &arr[0];
3) ptr = arr[0];
  1. ptr = arr: This statement assigns the address of the first element of the array arr to the pointer ptr. In C and C++, when an array is used in most contexts, it decays into a pointer to its first element. So, arr effectively represents the address of the first element, making ptr point to the same location as arr.
  2. ptr = &arr[0] : This statement explicitly takes the address of the first element of the array arr using the & (address-of) operator and assigns it to the pointer ptr. This is equivalent to the previous expression ptr = arr.
  3. ptr = arr[0]: This statement attempts to assign the value of the first element of the array arr to the pointer ptr, which is not correct. arr[0] represents the value stored at the first element of the array, not its address. Therefore, this expression would result in a type mismatch error.

Why Data Type Associated with Pointer

Have you ever wondered when declare an pointer it basically stores the memory address which is independent of the data type, But why?

Specifying the data type when declaring a pointer is crucial because it determines the interpretation of the data at the memory address it points to. While a pointer indeed stores memory addresses, the type information associated with the pointer is essential for proper dereferencing and manipulation of data. Here's why specifying the data type is necessary:

1 Dereferencing:

  1. When you dereference a pointer (accessing the value it points to), the compiler needs to know the type of data stored at that memory address. Specifying the data type of the pointer allows the compiler to correctly interpret the data when you dereference it.
int x = 10;
int *ptr = &x;  // Pointer to an integer
std::cout << *ptr;  // Dereferencing ptr to get the value stored at the memory address it points to

2 Pointer Arithmetic:

  1. If you perform pointer arithmetic, the compiler needs to know the size of the data type the pointer points to. When you increment or decrement a pointer, the compiler automatically adjusts the address based on the size of the data type.
int arr[5] = {1, 2, 3, 4, 5};
int *ptr = arr;  // Pointer to the first element of the array
ptr++;  // Move the pointer to the next integer element in the array

3 Memory Allocation:

  1. When dynamically allocating memory using new or malloc functions, specifying the data type informs the compiler how much memory to allocate. This ensures that the correct amount of memory is reserved for the data type.
int *ptr = new int;  // Allocating memory for an integer

4 Pointer Type Safety:

  1. Specifying the data type of the pointer adds type safety to your code. It helps prevent unintended data type conversions or memory access errors.