C Pointers In C

C Pointers In C

Pointers are indeed a fundamental concept in the C programming language. They are used to store memory addresses of variables, functions, and other pointers, enabling powerful features like low-level memory access, dynamic memory allocation, and more. Pointers are a crucial tool for manipulating and managing memory and data structures in C.

What is a Pointer in C?

A pointer is indeed a derived data type that can store the memory address of other C variables or memory locations. Using pointers, you can access and manipulate the data stored in the memory locations they point to. This capability is essential for tasks such as dynamic memory allocation, data structure manipulation, and low-level memory access in the C programming language.

Syntax

The syntax of pointers will be similar to the variable declaration in C, however, we can use the ( * ) dereferencing operator in the pointer declaration.

datatype * ptr;

where

  • ptr – Name of the pointer.
  • datatype – The type of data it is pointing to.

How to Use Pointers?

The use of pointers can be classified into 3 :

  1. Pointer Declaration
  2. Pointer Initialization
  3. Dereferencing

1. Pointer Declaration

In pointer declaration, we will declare the pointer won’t initialize it. To declare a pointer, we have to use the ( * ) dereference operator before its name.

Example

int *ptr;

The pointer which is declared will hence point to some random memory address as it is not initialized. Such pointers are called wild pointers.

2. Pointer Initialization

When initializing a pointer in C, you typically assign an initial value that is a memory address. The & (ampersand) operator is used to obtain the memory address of a variable, and you can store that memory address in a pointer variable.

int var = 10;
int * ptr;
ptr = &var;

Although, We can also declare and initialize the pointer in a single step. Therefore, This method is called pointer definition as the pointer is declared and initialized at a time.

Example

int *ptr = &var;

3. Dereferencing

Dereferencing a pointer in C involves using the * (asterisk) operator to access the value stored in the memory address specified by the pointer. This allows you to work with the actual data pointed to by the pointer.

Pointer In C Example


// C program to illustrate Pointers
#include <stdio.h>
 
void geeks()
{
    int var = 10;
 
    // declare pointer variable
    int* ptr;
 
    // note that data type of ptr and var must be same
    ptr = &var;
 
    // assign the address of a variable to a pointer
    printf("Value at ptr = %p \n", ptr);
    printf("Value at var = %d \n", var);
    printf("Value at *ptr = %d \n", *ptr);
}
 
// Driver program
int main()
{
    geeks();
    return 0;
}

Output

Value at ptr = 0x7fff1038675c 
Value at var = 10 
Value at *ptr = 10 

Type Of Pointers

Pointers are classified into different types depending on the parameters. For instance, we can take a look at the type of variable stored in the memory location pointed by the pointer. Thus, the pointers can be classified into the following types:

1. Integer Pointers

Integer pointers will point to the integer values

Syntax

int *ptr;

They are also referred as the Pointer to integer

Indeed, a pointer can point to any primitive data type. Moreover, It can also point to derived data types such as arrays and user-defined data types such as structures.

2. Array Pointer

Pointers and arrays are closely related in C. An array name can be considered a pointer to its first element. This relationship is often referred to as “arrays and pointers” in C programming.

Syntax

char *ptr = &array_name;

3. Structure Pointer

The pointer pointing to Structure type is called Structure Pointer or Pointer to Structure

Syntax

struct struct_name *ptr;

In C, structure pointers are mostly seen in data structures such as linked lists, trees, etc.

4. Function Pointers

Function pointers will point to the functions. Although, they are different from the rest of the pointers in the sense that instead of pointing to the data, they will point to the code. For example, a function prototype – int func (int, char), the function pointer for this function will be.

Syntax

int (*ptr)(int, char);

5. Double Pointers

In C, you can define pointers that store the memory address of other pointers. These are referred to as double-pointers or pointers-to-pointer. Instead of pointing directly to a data value, they point to another pointer.

Syntax

datatype ** pointer_name;

Dereferencing Double Pointer

*pointer_name; // get the address stored in the inner level pointer
**pointer_name; // get the value pointed by inner level pointer


6. Null Pointer

Null pointers are the pointers that won’t point to any memory location. Also, it can developed by providing a value to the null pointer. Hence, pointer of any type can be given values.

data_type *pointer_name = NULL;
        or
pointer_name = NULL

7. Void Pointer

Void pointers, also known as generic pointers, are pointers that don’t have an associated data type. They are used to create more flexible and versatile pointers because they can point to data of any data type, and they can be typecasted to any other data type.

Syntax

void * pointer_name;

8. Wild Pointers

Wild pointers in C are pointers that have not been initialized with a valid memory address or have been left pointing to a memory location that is no longer valid. They can cause serious issues in programs, such as crashes, memory corruption, and unexpected behavior, because they lack a well-defined target.

int *ptr;
char *str;

9. Constant Pointers

A constant pointer is a pointer where the memory address is constant and cannot be modified once defined. It always points to the same memory address.

Syntax

data_type * const pointer_name;

10. Pointer to Constant

A pointer to a constant is a pointer where the memory address is not constant, but the data it points to is constant and cannot be modified through the pointer. The pointer itself can be changed to point to different memory locations

Syntax

const data_type * pointer_name;

Other Type of Pointers

These are specialized types of pointers with specific purposes:

  1. Far Pointer: A far pointer is typically 32-bit and can access memory outside the current segment. They are often used in segmented memory models.
  2. Dangling Pointer: A dangling pointer is a pointer that points to a memory location that has been deleted (or freed). Using a dangling pointer can lead to undefined behavior.
  3. Huge Pointer: A huge pointer is a 32-bit pointer that contains both a segment address and an offset address. These were used in older memory models.
  4. Complex Pointer: Complex pointers are pointers with multiple levels of indirection, often used in more advanced data structures.
  5. Near Pointer: A near pointer is used to store 16-bit addresses within the current segment, typically on a 16-bit machine.
  6. Normalized Pointer: A normalized pointer is a 32-bit pointer designed to have as much of its value in the segment register as possible. This was relevant in segmented memory models.
  7. File Pointer: A file pointer is a pointer to a FILE data type, often referred to as a stream pointer or a file pointer. It is used to interact with files and input/output operations in C.

These various types of pointers serve specific purposes and are used in different contexts, depending on the memory model and requirements of the application.

Size Of Pointers In C

Your explanation of pointer sizes in C is mostly accurate. The size of pointers in C is indeed determined by the operating system and CPU architecture, not the type they point to. However, the sizes you provided are not universally true for all systems. The actual size of pointers can vary depending on the platform and the compiler.

Here’s a more accurate description:

  • On many 64-bit systems, pointers are typically 8 bytes in size, as they store 64-bit memory addresses.
  • On many 32-bit systems, pointers are usually 4 bytes in size, as they store 32-bit memory addresses.

The reason for the same size of pointers of a specific architecture is consistent with your explanation: Pointers store memory addresses, and the size of memory addresses is determined by the CPU architecture, not the data type they point to. However, it’s important to note that there can be exceptions and variations on different platforms, so it’s always a good practice to use the sizeof operator to determine the size of pointers on a specific system.

How to find the size of pointers in C?

Example: C Program to find the size of different pointer types.



// C Program to find the size of different pointers types
#include <stdio.h>
 
// dummy structure
struct str {
};
 
// dummy function
void func(int a, int b){};
 
int main()
{
    // dummy variables definitions
    int a = 10;
    char c = 'G';
    struct str x;
 
    // pointer definitions of different types
    int* ptr_int = &a;
    char* ptr_char = &c;
    struct str* ptr_str = &x;
    void (*ptr_func)(int, int) = &func;
    void* ptr_vn = NULL;

    // printing sizes
    printf("Size of Integer Pointer  \t:\t%d bytes\n",
           sizeof(ptr_int));
    printf("Size of Character Pointer\t:\t%d bytes\n",
           sizeof(ptr_char));
    printf("Size of Structure Pointer\t:\t%d bytes\n",
           sizeof(ptr_str));
    printf("Size of Function Pointer\t:\t%d bytes\n",
           sizeof(ptr_func));
    printf("Size of NULL Void Pointer\t:\t%d bytes",
           sizeof(ptr_vn));
 
    return 0;
}

Output

Size of Integer Pointer      :    8 bytes
Size of Character Pointer    :    8 bytes
Size of Structure Pointer    :    8 bytes
Size of Function Pointer    :    8 bytes
Size of NULL Void Pointer    :    8 bytes

No matter what the type of pointer it is, the size of each and every pointer will be the same.

 The type declaration is needed in the pointer for dereferencing and pointer arithmetic purposes.

Pointer Arithmetic

Pointer arithmetic refers to the set of valid arithmetic operations that can be performed on pointers. These operations are different from regular mathematical calculations and are limited to a specific set of operations

  • Increment in a Pointer
  • Decrement in a Pointer
  • Addition of integer to a pointer
  • Subtraction of integer to a pointer
  • Subtracting two pointers of the same type
  • Comparison of pointers of the same type.
  • Assignment of pointers of the same type.
// C program to illustrate Pointer Arithmetic
 
#include <stdio.h>
 
int main()
{
 
    // Declare an array
    int v[3] = { 10, 100, 200 };
 
    // Declare pointer variable
    int* ptr;
 
    // Assign the address of v[0] to ptr
    ptr = v;
   for (int i = 0; i < 3; i++) {
 
        // print value at address which is stored in ptr
        printf("Value of *ptr = %d\n", *ptr);
 
        // print value of ptr
        printf("Value of ptr = %p\n\n", ptr);
 
        // Increment pointer ptr by 1
        ptr++;
    }
    return 0;
}

Output

Value of *ptr = 10
Value of ptr = 0x7ffe8ba7ec50

Value of *ptr = 100
Value of ptr = 0x7ffe8ba7ec54

Value of *ptr = 200
Value of ptr = 0x7ffe8ba7ec58

C Pointers And Arrays

In C, pointers and arrays are closely related, and the array name acts as a pointer constant to the address of the first element. Here are some key points:

  1. An array name, such as val, can be used interchangeably with &val[0] to refer to the address of the first element of the array.
  2. If you assign the value of this pointer constant to a non-constant pointer of the same type, you can access the elements of the array using that pointer.

Example 1 – Accessing Array Elements using Pointer with Array Subscript

// C Program to access array elements using pointer
#include <stdio.h>
 
void skill()
{
    // Declare an array
    int val[3] = { 5, 10, 15 };
 
    // Declare pointer variable
    int* ptr;
 
    // Assign address of val[0] to ptr.
    // We can use ptr=&val[0];(both are same)
    ptr = val;
 
    printf("Elements of the array are: ");
 
    printf("%d, %d, %d", ptr[0], ptr[1], ptr[2]);
 
    return;
}
 
// Driver program
int main()
{
    skill();
    return 0;
}

Output

Elements of the array are: 5 10 15

Example 2: Accessing Array Elements using Pointer Arithmetic



// C Program to access array elements using pointers
#include <stdio.h>
 
int main()
{
 
    // defining array
    int arr[5] = { 1, 2, 3, 4, 5 };
 
    // defining the pointer to array
    int* ptr_arr = &arr;
 
    // traversing array using pointer arithmetic
    for (int i = 0; i < 5; i++) {
        printf("%d ", *ptr_arr++);
    }
    return 0;
}

Output

1 2 3 4 5 

Use Of Pointers

Pointers are indeed a fundamental and essential concept in C, and they serve various purposes, including:

  1. Passing Arguments by Reference: Pointers allow functions to modify the original data in memory, providing a way to pass arguments by reference.
  2. Accessing Array Elements: Pointers are commonly used to traverse and manipulate array elements efficiently.
  3. Returning Multiple Values from Functions: By using pointers, functions can return multiple values or modify values outside of the function.
  4. Dynamic Memory Allocation: Pointers are crucial for dynamic memory allocation functions like malloc, calloc, and realloc to manage memory at runtime.
  5. Implementing Data Structures: Pointers are used to build complex data structures like linked lists, trees, and graphs.
  6. System-Level Programming: In low-level system programming, memory addresses are often used, and pointers provide a means to access and manipulate memory directly.
  7. Locating the Exact Value at a Memory Location: Pointers are used to access data at specific memory addresses.
  8. Avoiding Compiler Confusion: Pointers can be used to distinguish between variables with the same name in different scopes.
  9. Control Tables: Pointers can be used in data structures like control tables, which define the behavior of a program.

Overall, understanding and effectively using pointers is essential for a wide range of programming tasks in C, from basic memory manipulation to building complex data structures and working with low-level system programming.

Disadvantages of Pointers

  1. Memory Corruption with Incorrect Values: Providing incorrect values to pointers can indeed lead to memory corruption, especially when writing to memory locations that should not be accessed.
  2. Complexity of Pointers: Pointers can be complex to understand, especially for beginners, because they involve low-level memory manipulation and require a good understanding of memory management.
  3. Responsibility for Memory Leaks: Pointers can be a source of memory leaks in C if dynamically allocated memory is not properly deallocated with functions like free.
  4. Speed Compared to Variables: Pointers themselves are not inherently slower than variables. However, using pointers for certain operations might introduce a slight overhead, but in many cases, the performance difference is negligible.
  5. Uninitialized Pointers and Segmentation Faults: Uninitialized pointers can indeed cause segmentation faults, as they may point to random or invalid memory locations. It’s important to initialize pointers before using them to avoid such issues.

It’s crucial to handle pointers carefully, especially when working with memory allocation and manipulation, to prevent memory-related errors and issues like memory corruption and memory leaks.

FAQ- C Pointers In C

Q1. What is C pointer in C?

Ans. In C, a pointer is a variable that stores the memory address of another variable, which can be of various types. The size of a pointer is determined by the platform, typically 4 bytes in 32-bit architectures, but it can vary. Use sizeof to check the pointer size on your platform.

Q2. What is the use of pointers in C?

Ans. In C, pointers are essential for data structures, flexible array access, and file handling.

Q3. What is the syntax of pointer?

Ans. In C, you declare a pointer by adding a * before the name and associate it with a specific data type (e.g., int or double). It’s a common convention to use “p” or “ptr” as a prefix or suffix in pointer variable names, like iPtr, numberPtr, pNumber, or pStudent.

Hridhya Manoj

Hello, I’m Hridhya Manoj. I’m passionate about technology and its ever-evolving landscape. With a deep love for writing and a curious mind, I enjoy translating complex concepts into understandable, engaging content. Let’s explore the world of tech together

Leave a Comment