Pointer in c

By Paribesh Sapkota

What is a Pointer in C?

A pointer is defined as a derived data type that can store the address of other C variables or a memory location. We can access and manipulate the data stored in that memory location using pointers.

Syntax of C Pointers

The syntax of pointers is similar to the variable declaration in C, but we use the ( * ) dereferencing operator in the pointer declaration.

datatype * ptr;

where

  • ptr is the name of the pointer.
  • datatype is the type of data it is pointing to.

The above syntax is used to define a pointer to a variable. We can also define pointers to functions, structures, etc.

How to Use Pointers?

The use of pointers in C can be divided into three steps:

  1. Pointer Declaration
  2. Pointer Initialization
  3. Pointer Dereferencing

1. Pointer Declaration

In pointer declaration, we only declare the pointer but do not initialize it. To declare a pointer, we use the ( * ) dereference operator before its name.

Example

int *ptr;

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

2. Pointer Initialization

Pointer initialization is the process where we assign some initial value to the pointer variable. We generally use the ( & ) addressof operator to get the memory address of a variable and then store it in the pointer variable.

Example

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

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

Example

int *ptr = &var;

Advantages and disadvantages of pointer
Advantage:
  • Pointers provide direct access to memory
  • Pointers provide a way to return more than one value to the functions
  • Reduces the storage space and complexity of the program
  • Reduces the execution time of the program
  • Provides an alternate way to access array elements
Drawbacks of pointers in c:
  • Uninitialized pointers might cause segmentation fault.
  • Dynamically allocated block needs to be freed explicitly.  Otherwise, it would lead to memory leak.
  • Pointers are slower than normal variables.
  • If pointers are updated with incorrect values, it might lead to memory corruption.

The & and * operators play crucial roles when working with pointers:

  1. Address-of Operator (&):
    • The & operator is also known as the “address-of operator.”
    • It is used for referencing, which means taking the address of an existing variable.
    • When you use & in front of a variable, it gives you the memory address where that variable is stored.
      int i = 42;
      int* ptr = &i; // ptr now points to the memory location of 'i'
      

       

Dereference Operator (*):

  • The * operator is also known as the “dereference operator.”
  • It is used to access the value stored at a memory address pointed to by a pointer.
  • When you use * in front of a pointer, it retrieves the value stored at that memory location.
int j = *ptr; // 'j' now holds the value 42 (retrieved from the memory location pointed to by 'ptr')

Pointer to Pointer (Pointer-to-Pointer):

  • Sometimes, you need to work with pointers that point to other pointers.
  • The & operator can create a pointer to a pointer (a pointer-to-pointer).
    int** ipp; // Declare a pointer to a pointer
    int k = 99;
    int* ip1 = &k; // 'ip1' points to 'k'
    ipp = &ip1; // 'ipp' now points to 'ip1'
    

    Pointer Arithmetic

    The Pointer arithmetic refers to the legal or valid arithmetic operations that can be performed on a pointer. It is slightly different from the ones that we generally use for mathematical calculations as only a limited set of operations can be performed on pointers. These operations include:

    • 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.

Incrementing Pointer in C

If we increment a pointer by 1, the pointer will start pointing to the immediate next location. This is somewhat different from the general arithmetic since the value of the pointer will get increased by the size of the data type to which the pointer is pointing.

The Rule to increment the pointer is given below:

  1. new_address= current_address + i * size_of(data type)

Where i is the number by which the pointer get increased.

32-bit

For 32-bit int variable, it will be incremented by 2 bytes.

64-bit

For 64-bit int variable, it will be incremented by 4 bytes.

#include<stdio.h>  
int main(){  
int number=50;        
int *p;//pointer to int      
p=&number;//stores the address of number variable        
printf("Address of p variable is %u \n",p);        
p=p+1;        
printf("After increment: Address of p variable is %u \n",p); // in our case, p will get incremented by 4 bytes.      
return 0;  
}

Decrementing Pointer in C

Like increment, we can decrement a pointer variable. If we decrement a pointer, it will start pointing to the previous location. The formula of decrementing the pointer is given below:

  1. new_address= current_address – i * size_of(data type)

32-bit

For 32-bit int variable, it will be decremented by 2 bytes.

64-bit

For 64-bit int variable, it will be decremented by 4 bytes.

#include <stdio.h>            
void main(){            
int number=50;        
int *p;//pointer to int      
p=&number;//stores the address of number variable        
printf("Address of p variable is %u \n",p);        
p=p-1;       
printf("After decrement: Address of p variable is %u \n",p); // P will now point to the immidiate previous location.         
}      

Pointer Addition

#include<stdio.h>  
int main(){  
int number=50;        
int *p;//pointer to int      
p=&number;//stores the address of number variable        
printf("Address of p variable is %u \n",p);        
p=p+3;   //adding 3 to pointer variable    
printf("After adding 3: Address of p variable is %u \n",p);       
return 0;  
}

Pointer Subtraction

#include<stdio.h>  
int main(){  
int number=50;        
int *p;//pointer to int      
p=&number;//stores the address of number variable        
printf("Address of p variable is %u \n",p);        
p=p-3; //subtracting 3 from pointer variable    
printf("After subtracting 3: Address of p variable is %u \n",p);        
return 0;  
}

Illegal arithmetic with pointers

There are various operations which can not be performed on pointers. Since, pointer stores address hence we must ignore the operations which may lead to an illegal address, for example, addition, and multiplication. A list of such operations is given below.

  • Address + Address = illegal
  • Address * Address = illegal
  • Address % Address = illegal
  • Address / Address = illegal
  • Address & Address = illegal
  • Address ^ Address = illegal
  • Address | Address = illegal
  • ~Address = illegal

Pointer to function

#include<stdio.h>  
int addition ();  
int main ()  
{  
    int result;   
    int (*ptr)();  
    ptr = &addition;  
    result = (*ptr)();  
    printf("The sum is %d",result);  
}  
int addition()  
{  
    int a, b;   
    printf("Enter two numbers?");  
    scanf("%d %d",&a,&b);  
    return a+b;  
}

Array of functions in C

#include<stdio.h>  
int show();  
int showadd(int);  
int (*arr[3])();  
int (*(*ptr)[3])();  
  
int main ()  
{  
    int result1;  
    arr[0] = show;  
    arr[1] = showadd;  
    ptr = &arr;  
    result1 = (**ptr)();  
    printf("printing the value returned by show : %d",result1);  
    (*(*ptr+1))(result1);  
}  
int show()  
{  
    int a = 65;  
    return a++;  
}  
int showadd(int b)  
{  
    printf("\nAdding 90 to the value returned by show: %d",b+90);  
}

Pointers and Character Strings

Strings in C are arrays of characters, and pointers can be used to manipulate them.

char str[] = "Hello";
char *ptr = str;

while (*ptr != '\0') {
    printf("%c", *ptr);
    ptr++;
}

Array of Pointers

An array of pointers can be used to store a list of strings.

char *arr[] = {"Hello", "World", "C Programming"};
for (int i = 0; i < 3; i++) {
    printf("%s\n", arr[i]);
}

Pointers as Function Arguments

Pointers can be passed to functions to modify the original variables.

void increment(int *ptr) {
    (*ptr)++;
}

int main() {
    int num = 10;
    increment(&num);
    printf("%d\n", num); // Outputs 11
}

Function Returning Pointers

Functions can return pointers, allowing for dynamic memory allocation within functions.

#include <stdlib.h>

int* createArray(int size) {
    int *arr = (int *)malloc(size * sizeof(int));
    for (int i = 0; i < size; i++) {
        arr[i] = i + 1;
    }
    return arr;
}

int main() {
    int *arr = createArray(5);
    for (int i = 0; i < 5; i++) {
        printf("%d ", arr[i]);
    }
    free(arr);
}

Pointers and Structures

Pointers to structures allow for efficient manipulation and dynamic allocation of complex data types.

struct Point {
    int x, y;
};

void printPoint(struct Point *p) {
    printf("Point(%d, %d)\n", p->x, p->y);
}

int main() {
    struct Point p1 = {10, 20};
    printPoint(&p1);
}

Dynamic Memory Allocation

Dynamic memory allocation is a powerful feature in C that allows you to allocate memory during program execution. This enables you to create data structures of varying sizes and lifetimes, such as arrays, linked lists, trees, and more. Dynamic memory allocation is typically done using the malloc, calloc, realloc, and free functions from the <stdlib.h> library.

malloc Function

The malloc function allocates a block of memory of a specified size and returns a pointer to the beginning of the block

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

int main() {
    int *ptr;

    // Allocate memory for 5 integers
    ptr = (int *)malloc(5 * sizeof(int));

    if (ptr == NULL) {
        printf("Memory allocation failed\n");
        return 1;
    }

    // Use the allocated memory
    for (int i = 0; i < 5; i++) {
        ptr[i] = i + 1;
        printf("%d ", ptr[i]);
    }

    // Free the allocated memory
    free(ptr);

    return 0;
}

calloc Function

The calloc function is used to allocate memory for an array of elements, initialized to zero.

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

int main() {
    int *ptr;

    // Allocate memory for 5 integers initialized to zero
    ptr = (int *)calloc(5, sizeof(int));

    if (ptr == NULL) {
        printf("Memory allocation failed\n");
        return 1;
    }

    // Use the allocated memory
    for (int i = 0; i < 5; i++) {
        printf("%d ", ptr[i]); // Will print all zeros
    }

    // Free the allocated memory
    free(ptr);

    return 0;
}

realloc Function

The realloc function changes the size of the previously allocated memory block. It may move the block to a new location in memory.

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

int main() {
    int *ptr;

    // Allocate memory for 5 integers
    ptr = (int *)malloc(5 * sizeof(int));

    if (ptr == NULL) {
        printf("Memory allocation failed\n");
        return 1;
    }

    // Use the allocated memory
    for (int i = 0; i < 5; i++) {
        ptr[i] = i + 1;
        printf("%d ", ptr[i]);
    }

    // Reallocate memory for 10 integers
    ptr = (int *)realloc(ptr, 10 * sizeof(int));

    if (ptr == NULL) {
        printf("Memory reallocation failed\n");
        return 1;
    }

    // Use the reallocated memory
    for (int i = 5; i < 10; i++) {
        ptr[i] = i + 1;
        printf("%d ", ptr[i]);
    }

    // Free the allocated memory
    free(ptr);

    return 0;
}

free Function

The free function deallocates the memory previously allocated by malloc, calloc, or realloc.

Important Questions
Comments
Discussion
0 Comments
  Loading . . .