POINTERS IN C

Dev Frank
5 min readFeb 16, 2024

--

Pointers are a fundamental concept in the C programming language, and they allow you to work with memory directly. Understanding pointers is crucial for advanced programming and data manipulation.

WHAT ARE POINTERS?

Pointers are variable that stores the memory address of another variable. Instead of holding the actual value, it holds the location (address) of where the value is stored in the computer’s memory.

It is like a guide that knows the exact location of some information in a computer’s memory. Rather than keeping the actual data, a pointer stores the precise location in the computer’s memory where the data is kept.

SYNTAX OF C POINTERS

The structure for declaring pointers in C resembles the syntax for declaring variables. However, in pointer declarations, we incorporate the ( * ) dereferencing operator.

datatype *ptr;

Here,

  • ptr is the chosen name for the pointer.
  • datatype specifies the type of data the pointer is pointing to.

This syntax is employed to establish a pointer directed at a variable. It’s important to note that we can also define pointers intended for functions, structures, and other data types using a similar approach.

Let’s break down the key aspects of pointers in C:

  1. Declaration of Pointers:

In the process of declaring a pointer, we specify the pointer without providing it with an initial value. The declaration involves using the ( * ) dereference operator preceding the pointer’s name.

When we want to use a pointer, we need to tell the computer that we’ll be using one.

To declare a pointer, you use the * (asterisk) symbol.

For example:

int *ptr;

This declares a pointer named ptr that can point to an integer.

Note:

There are two ways to declare pointer variables in C:

int* ptr;
int *ptr;

2. Initializing Pointers:

Pointer initialization involves assigning an initial value to the pointer variable. Typically, we utilize the ( & ) address-of operator to obtain the memory address of a variable and subsequently store it in the pointer variable.

After declaring a pointer, it’s a good practice to initialize it with the address of a variable of the correct type.

int x = 10;
int *ptr = &x; // ptr now holds the address of x

Accessing the Value at the Address (Dereferencing):

To access the value stored at the memory address a pointer is pointing to, you use the * operator again.

For example:

int value = *ptr; // value now contains the value of x

3. Pointer Arithmetic:

Pointers can be incremented and decremented, which is especially useful for working with arrays.

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

int element = *arrPtr; // accessing the first element
arrPtr++; // moving to the next element

4. Null Pointers:

Pointers can also be assigned a special value called NULL to indicate that they are not pointing to any valid memory location.

int *ptr = NULL; // ptr is a null pointer

5. Pointer and Arrays:

Arrays and pointers have a close relationship in C. An array name can be used as a pointer to its first element.

int arr[3] = {10, 20, 30};
int *arrPtr = arr; // arr and arrPtr are equivalent

6. Dynamic Memory Allocation:

Pointers are often used in conjunction with functions like malloc() and free() for dynamic memory allocation. Pointers are used when we need the computer to set aside some memory space for us on the go.

int *dynamicArr = (int *)malloc(5 * sizeof(int)); //  computer reserves space for an array

TYPES OF POINTERS

In C, there are several types of pointers, each designed to handle different data types or situations. Here are some common types of pointers:

  1. Integer Pointers:
    Pointers that are designed to store the memory addresses of integer variables.
int *intPtr;

2. Character Pointers:
Pointers specifically intended for character data.

char *charPtr;

3. Floating Point Pointers:
Pointers tailored for floating-point (decimal) data.

float *floatPtr;

4. Void Pointers:
Versatile pointers that can be used to store the address of any data type. They are often used in dynamic memory allocation.

void *genericPtr;

5. Pointer to Pointer (Double Pointer):
Pointers that store the address of another pointer. These are useful in situations where you need to modify the original pointer.

int **doubleIntPtr;

6. Array Pointers:
Pointers used to traverse arrays or store the base address of an array.

int arr[5];
int *arrPtr = arr;

7. Function Pointers:
Pointers that store the address of functions, allowing you to call functions indirectly.

int (*functionPtr)(int, int);

8. Null Pointers:
Pointers that do not point to any valid memory address. They are often used to indicate that a pointer is not currently pointing anywhere.

int *nullPtr = NULL;

9. Wild Pointers:
Uninitialized pointers that can point to any memory location. Using these pointers can lead to unpredictable behavior and should be avoided.

data_type * const pointer_name;

10. Constant Pointers
Pointers that point to a constant value, which remains unalterable, are known as constant pointers. In this scenario, we can solely access the data indicated by the pointer but are restricted from making any modifications. Nevertheless, we retain the ability to update the memory address stored in the constant pointer.

Syntax

const data_type * pointer_name;

Size of Pointers in C

The size of pointers in C remains consistent across different pointer types. It is not influenced by the type of data they point to; instead, it is determined by the characteristics of the operating system and CPU architecture.

  • 8 bytes for a 64-bit System
  • 4 bytes for a 32-bit System

The uniform size arises from the fact that pointers store memory addresses, irrespective of the data type they reference. Since the space needed to store these addresses is identical, the memory requirements for pointers of various types are equivalent.

Determining the Size of Pointers in C

To ascertain the size of pointers in C, the sizeof operator can be employed, as demonstrated in the subsequent program:

#include <stdio.h>

int main() {
int *intPtr;
char *charPtr;
float *floatPtr;

printf("Size of an integer pointer: %zu bytes\n", sizeof(intPtr));
printf("Size of a character pointer: %zu bytes\n", sizeof(charPtr));
printf("Size of a float pointer: %zu bytes\n", sizeof(floatPtr));

return 0;
}

The output of the program will depend on the system and compiler you are using. However, based on common scenarios:

If you are working on a 32-bit system:

Size of an integer pointer: 4 bytes
Size of a character pointer: 4 bytes
Size of a float pointer: 4 bytes

If you are working on a 64-bit system:

Size of an integer pointer: 8 bytes
Size of a character pointer: 8 bytes
Size of a float pointer: 8 bytes

NOTE:

It’s important to note that the * sign can be a source of confusion in our code because it serves two distinct purposes:

1. In declarations (e.g., int* ptr), it designates the creation of a pointer variable.
2. Outside of declarations, it functions as a dereference operator.

--

--

Dev Frank

Passionate tech enthusiast, diving deep into the world of software engineering. Thrilled to share insights with the world. A Software engineering student.