# Pointers

## **What is a Pointer?**

A pointer is a variable that **stores the address** of another variable. Instead of holding a data value, a pointer holds the location of that value in memory.

**Pointer Basics**

* **Declaration:** You declare a pointer by specifying the type of data it points to, followed by an asterisk `*`.

  ```c
  int *ptr;  // Pointer to an integer
  ```
* **Initialization:** You assign a pointer the address of a variable using the address-of operator `&`.

  ```c
  int x = 10;
  int *ptr = &x;  // 'ptr' now holds the address of 'x'
  ```
* **Dereferencing:** To access the value stored at the address a pointer points to, you use the dereference operator `*`.

  ```c
  int value = *ptr;  // Retrieves the value at the address stored in 'ptr'
  ```

***

#### **Pointer Example**

Here’s a simple example showing how pointers work:

```c
#include <stdio.h>

int main() {
    int x = 10;         // Regular integer variable
    int *ptr = &x;      // Pointer variable that holds the address of 'x'
    
    printf("Value of x: %d\n", x);        // Outputs: Value of x: 10
    printf("Address of x: %p\n", &x);    // Outputs the memory address of 'x'
    printf("Value of ptr: %p\n", ptr);   // Outputs the address stored in 'ptr'
    printf("Value pointed to by ptr: %d\n", *ptr);  // Outputs: Value pointed to by ptr: 10
    
    return 0;
}
```

**Explanation:**

* `int *ptr = &x;` initializes the pointer `ptr` with the address of `x`.
* `*ptr` is used to access the value of `x` through the pointer.

***

#### **Pointer Arithmetic**

Pointers can be incremented or decremented to point to different memory locations. This is especially useful with arrays.

**Example: Pointer Arithmetic with Arrays**

```c
#include <stdio.h>

int main() {
    int arr[] = {10, 20, 30};
    int *ptr = arr;  // Pointer to the first element of the array
    
    printf("First element: %d\n", *ptr);         // Outputs: 10
    printf("Second element: %d\n", *(ptr + 1));  // Outputs: 20
    printf("Third element: %d\n", *(ptr + 2));   // Outputs: 30
    
    return 0;
}
```

**Explanation:**

* `ptr + 1` moves the pointer to the next integer (4 bytes away in most systems).
* `*(ptr + 1)` accesses the second element of the array.

***

#### **Dynamic Memory Allocation**

Pointers are used to allocate memory dynamically at runtime using functions from the `<stdlib.h>` library.

**Functions:**

* **`malloc(size_t size)`**: Allocates memory.
* **`free(void *ptr)`**: Frees allocated memory.
* **`calloc(size_t num, size_t size)`**: Allocates memory and initializes it to zero.
* **`realloc(void *ptr, size_t newSize)`**: Resizes previously allocated memory.

**Example: Using `malloc` and `free`**

```c
#include <stdio.h>
#include <stdlib.h>

int main() {
    int *arr = (int *)malloc(3 * sizeof(int));  // Allocate memory for 3 integers
    
    if (arr == NULL) {
        printf("Memory allocation failed\n");
        return 1;
    }
    
    arr[0] = 10;
    arr[1] = 20;
    arr[2] = 30;
    
    printf("First element: %d\n", arr[0]);   // Outputs: 10
    printf("Second element: %d\n", arr[1]);  // Outputs: 20
    printf("Third element: %d\n", arr[2]);   // Outputs: 30
    
    free(arr);  // Free the allocated memory
    
    return 0;
}
```

**Explanation:**

* `malloc` allocates memory on the heap.
* Always check if `malloc` returns `NULL` to handle memory allocation failures.
* `free` releases the allocated memory to avoid memory leaks.

***

#### **Pointers and Functions**

Pointers can be passed to functions to allow modifications to the original data or to handle large amounts of data efficiently.

**Example: Modifying Data Using Pointers**

```c
#include <stdio.h>

void increment(int *p) {
    (*p)++;  // Increment the value pointed to by 'p'
}

int main() {
    int num = 5;
    increment(&num);  // Pass the address of 'num'
    printf("Incremented value: %d\n", num);  // Outputs: Incremented value: 6
    return 0;
}
```

**Explanation:**

* `increment(&num)` passes the address of `num` to the function.
* `(*p)++` modifies the value of `num` through the pointer.

***

#### **Pointers to Pointers**

A pointer to a pointer is a variable that stores the address of another pointer.

**Example:**

```c
#include <stdio.h>

int main() {
    int x = 10;
    int *ptr = &x;
    int **pptr = &ptr;
    
    printf("Value of x: %d\n", x);                // Outputs: 10
    printf("Value pointed to by ptr: %d\n", *ptr); // Outputs: 10
    printf("Value pointed to by pptr: %d\n", **pptr); // Outputs: 10
    
    return 0;
}
```

**Explanation:**

* `ptr` is a pointer to `x`.
* `pptr` is a pointer to `ptr`.

***

#### **Summary**

* **Pointers** store addresses of variables.
* **Dereferencing** `*` accesses the value at the pointer’s address.
* **Pointer Arithmetic** allows moving through arrays.
* **Dynamic Memory Allocation** uses `malloc`, `calloc`, `realloc`, and `free`.
* **Pointers in Functions** enable modifications to original data.
* **Pointers to Pointers** involve multiple levels of indirection.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://cs.d19.in/pointers.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
