Pointers

Pionter is a special type of variable which is used to hold the address of any other variable.

In C programming, a pointer is a variable that stores the memory address of another variable. Pointers are used to directly manipulate memory and facilitate dynamic memory allocation.

Here are some key points about pointers in C:

  • Declaration: Pointers are declared using the asterisk (*) symbol before the variable name. For example:
    int *ptr;  // Pointer to an integer
    char *ch;   // Pointer to a character
    float *fp;  // Pointer to a float
    
  • Initialization: Pointers can be initialized with the address of another variable using the address-of operator (&). For example:
    int x = 10;
    int *ptr = &x; // ptr now points to the address of x
    
  • Dereferencing: Dereferencing a pointer means accessing the value stored at the memory address it points to. This is done using the asterisk (*) symbol before the pointer variable name. For example:
    int value = *ptr; // value now contains the value stored at the memory location pointed by ptr
    
    Example:
    #include <stdio.h>
    
    int main() {
        int x = 10;
        int *ptr = &x; //Referencing
        
        printf("Value of x: %d\n", x);
        printf("Address of x: %p\n", &x);
        printf("Value pointed by ptr: %d\n", *ptr); //*ptr --Dereferencing
        printf("Address stored in ptr: %p\n", ptr);
        
        return 0;
    }
    
    
    Output:
    Value of x: 10
    Address of x: 000000000062FE14
    Value pointed by ptr: 10
    Address stored in ptr: 000000000062FE14
    
    Concepts Covered:
    • Declaring and initializing pointers (int *ptr = &x;)
    • Dereferencing pointers (*ptr)
    • Accessing memory addresses (&x, ptr)
    • Printing memory addresses (%p format specifier)


  • Pointer Arithmetic: Pointers in C can be incremented or decremented to navigate through memory. When performing arithmetic operations on pointers, the size of the data type being pointed to is taken into account. For example:
    ptr++; // Moves ptr to the next memory location of type int
    
    Example:
    #include <stdio.h>
    
    int main() {
        int i,arr[5] = {1, 2, 3, 4, 5};
        int *ptr = arr;
    
        for (i = 0; i < 5; i++) {
            printf("Element %d: %d\n", i+1, *(ptr + i));
        }
    
        return 0;
    }
    
    Output:
    Element 1: 1
    Element 2: 2
    Element 3: 3
    Element 4: 4
    Element 5: 5
    
    Concepts Covered:
    • Pointer arithmetic (ptr + i)
    • Dereferencing pointers (*(ptr + i))
    • Array indexing using pointers


  • Dynamic Memory Allocation: Pointers are used extensively in dynamic memory allocation functions like malloc(), calloc(), and realloc() to allocate memory during program execution. For example:
    int *dynamicArray = (int *)malloc(5 * sizeof(int));
    
    Example:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main() {
        int i, *dynamicArray = (int *)malloc(5 * sizeof(int));
    
        if (dynamicArray == NULL) {
            printf("Memory allocation failed!\n");
            return 1;
        }
    
        for ( i = 0; i < 5; i++) {
            dynamicArray[i] = i * 10;
        }
    
        for ( i = 0; i < 5; i++) {
            printf("Element %d: %d\n", i+1, dynamicArray[i]);
        }
    
        free(dynamicArray);
    
        return 0;
    }
    
    Output:
    Element 1: 0
    Element 2: 10
    Element 3: 20
    Element 4: 30
    Element 5: 40
    
    Concepts Covered:
    • Dynamic memory allocation (malloc())
    • Checking for allocation success or failure
    • Dynamic array usage


  • Null Pointers: Pointers can be explicitly set to NULL to indicate that they are not pointing to any valid memory address. It's good practice to initialize pointers to NULL when they are declared. For example:
    int *ptr = NULL;
    
    Example:
    #include <stdio.h>
    
    int main() {
        int *ptr = NULL;
    
        if (ptr == NULL) {
            printf("Pointer is NULL\n");
        } else {
            printf("Pointer is not NULL\n");
        }
    
        return 0;
    }
    
    Output:
    Pointer is NULL
    
    Concepts Covered:
    • Initializing pointers to NULL (int *ptr = NULL;)
    • Checking for NULL pointers


  • Pointer to Pointer: Pointers in C can themselves be pointed to by other pointers, creating a chain of references. These are known as "pointer to pointer" or double pointers. For example:
    int x = 10;
    int *ptr1 = &x;
    int **ptr2 = &ptr1;
    
    Example:
    #include <stdio.h>
    
    int main() {
        int x = 10;
        int *ptr1 = &x;
        int **ptr2 = &ptr1;
    
        printf("Value of x: %d\n", x);
        printf("Value pointed by ptr1: %d\n", *ptr1);
        printf("Value pointed by ptr2: %d\n", **ptr2);
    
        return 0;
    }
    
    Output:
    Value of x: 10
    Value pointed by ptr1: 10
    Value pointed by ptr2: 10
    
    Concepts Covered:
    • Pointer to pointer declaration (int **ptr2 = &ptr1;)
    • Dereferencing pointer to pointer (**ptr2)


Operatoins on pointer in c

In C programming, there are several arithmetic operations you can perform on pointers, but it's essential to be cautious and understand memory layout to avoid accessing invalid memory locations. Here are the main operations:



Comparing Pointers:

Comparing pointers involves checking whether they hold the same memory address, indicating whether they point to the same location in memory or not.


Syntex:
int *ptr1 = &x;
int *ptr2 = &y;
if (ptr1 == ptr2) {
    // Pointers point to the same location
} else {
    // Pointers point to different locations
}
Explanation:
  • Compares two pointers to see if they point to the same memory location.
  • Equality comparison (==) checks if both pointers hold the same address.


Here's a simple C program that demonstrates comparing two pointers and checking if they point to the same location or different locations:

#include <stdio.h>

int main() {
    int x = 10;
    int y = 20;
    
    int *ptr1 = &x;
    int *ptr2 = &y;
    
    if (ptr1 == ptr2) {
        printf("Pointers point to the same location\n");
    } else {
        printf("Pointers point to different locations\n");
    }
    
    return 0;
}
Output:
Pointers point to different locations


Null Pointer Check:

Null Pointer Check ensures that a pointer does not contain a null value before dereferencing it, preventing potential program crashes or undefined behavior.

int *ptr = NULL;
if (ptr != NULL) {
    // Pointer is not NULL
} else {
    // Pointer is NULL
}
Explanation:
  • Checks if a pointer is NULL or not.
  • NULL is a macro defined in that represents a null pointer.


Here's a simple C program that demonstrates comparing a pointer to NULL:

#include <stdio.h>
#include <stddef.h>
int main() {
    int *ptr = NULL;
    
    if (ptr != NULL) {
        printf("Pointer is not NULL\n");
    } else {
        printf("Pointer is NULL\n");
    }
    
    return 0;
}
Output:
Pointer is NULL


Increment (++) and Decrement (--)

These operators move the pointer to the next or previous memory location based on the data type it points to. The amount of movement depends on the size of the data type:

Syntex:
int arr[] = {1, 2, 3, 4, 5};
int *ptr = arr; // ptr points to arr[0]

ptr++;  // ptr now points to arr[1] (increments by sizeof(int))
ptr--;  // ptr now points back to arr[0]


here's a simple C program that demonstrates the use of the increment operator with pointers.

#include <stdio.h>

int main() {
    int i,array[] = {1, 2, 3, 4, 5};
    int *ptr = array; // Pointer pointing to the first element of the array
    
    printf("Original array: ");
    for( i = 0; i < 5; i++) {
        printf("%d ", array[i]);
    }
    printf("\n");
    
    printf("Incrementing each element using pointers: ");
    for( i = 0; i < 5; i++) {
        printf("%d ", *ptr);
        ptr++; // Moving the pointer to the next element
    }
    printf("\n");
    
    return 0;
}
Original array: 1 2 3 4 5
Incrementing each element using pointers: 1 2 3 4 5

In this program, we declare an integer array array and a pointer ptr to an integer. We initialize the pointer ptr to point to the first element of the array. Then, we use a loop to increment each element of the array using the pointer ptr and print the incremented values. Finally, we move the pointer ptr to the next element in each iteration of the loop using the increment operator ptr++.



here's a simple C program that demonstrates the use of the decrement operator with pointers.

#include <stdio.h>

int main()
{
	int i, array[] = {1, 2, 3, 4, 5}; // Array in reverse order
	int *ptr = array + 4;			  // Pointer pointing to the last element (index 4)

	printf("Original array: \n");
	for (i = 0; i < 5; i++)
	{
		printf("%d ", array[i]);
	}
	printf("\n");

	ptr = &array[4];
	printf("Decrementing each element using pointers: \n");
	for (i = 0; i < 5; i++)
	{
		printf("%d ", *ptr);
		ptr--; // Move the pointer to the previous element
	}
	printf("\n");

	return 0;
}

Output:
Original array:
1 2 3 4 5
Decrementing each element using pointers:
5 4 3 2 1

In this modified program, the array array is initialized in reverse order to demonstrate decrementing. The rest of the program remains similar to the previous one, with the exception that now we are using the decrement operator -- instead of the increment operator ++ to decrement the value at the memory location pointed to by ptr, and we move the pointer ptr to the previous element in each iteration of the loop using the decrement operator ptr--.



Addition (+) and Subtraction (-) with Integers

You can add or subtract an integer value to a pointer to move it a specific number of memory locations:

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

ptr = ptr + 2;  // ptr now points to arr[2] (adds 2 * sizeof(int))
ptr = ptr - 1;  // ptr now points back to arr[1] (subtracts 1 * sizeof(int))

Subtraction (-) with another pointer of the same type

int arr[] = {1, 2, 3, 4, 5};
int *ptr1 = arr;
int *ptr2 = arr + 2;  // ptr2 points to arr[2]

int distance = ptr2 - ptr1;  // distance will be 2 (difference in indices)
If you subtract two pointers pointing to elements of the same array or compatible types, the result is the distance between those elements in terms of the data type's size:
Example:1
1.First pointer program

#include<stdio.h>
int main()
{
    int x=5;
    int *PTR1;// pointer declaration
    PTR1=&x; // pointer variable assignment
    int **PTR2;
    PTR2=&PTR1;
    int ***PTR3=&PTR2;
    printf("The value of x is : %d   ::  Address is : %d\n",x,&x);
    printf("The value of x is : %d   ::  value of x is : %d\n",x,*(&x));
    printf("The Address of x is : %d   ::  Address of is PTR1 : %d\n",PTR1,&PTR1);
    printf("The value of x is : %d   ::  Address is : %d\n",PTR2,&PTR2);
    printf("The value of x is : %d   ::  Address is : %d\n",PTR3,&PTR3);
    printf("The value of x is : %d   ::  Address is : %d\n",PTR3,*PTR3);
    printf("The value of x is : %d   ::  Address is : %d\n",PTR3,****(&PTR3));


}
        
        
Output:
            The value of x is : 5   ::  Address is : 6487580
            The value of x is : 5   ::  value of x is : 5
            The Address of x is : 6487580   ::  Address of is PTR1 : 6487568
            The value of x is : 6487568   ::  Address is : 6487560
            The value of x is : 6487560   ::  Address is : 6487552
            The value of x is : 6487560   ::  Address is : 6487568
            The value of x is : 6487560   ::  Address is : 5

            --------------------------------
            Process exited after 0.07429 seconds with return value 49
            Press any key to continue . . .
        
Example:2
2.Operation on the pointers

    #include<stdio.h>

    int main()
    {
        int x=5;
        int y=6;
        int *PTR1=&x;
        int *PTR2=&y;
        printf("The value of x =%d\n",*PTR1);
        printf("The value of y =%d\n\n\n",*PTR2);

        PTR1=PTR2;

        printf("The value of x =%d\n",*PTR1);
        printf("The value of y =%d\n",*PTR2);

    }
   
        
Output:
            The value of x =5
            The value of y =6


            The value of x =6
            The value of y =6

            --------------------------------
            Process exited after 0.04261 seconds with return value 18
            Press any key to continue . . .
        
Example:3
3.Operation on the pointers

    #include<stdio.h>

    int main()
    {
        int x=5;
        int y=6;
        int *PTR1=&x;
        int *PTR2=&y;
        printf("The value of x =%d\n",*PTR1);
        printf("The value of y =%d\n\n\n",*PTR2);

        PTR1=PTR2;

        printf("The value of *PTR1 =%d\n",*PTR1);
        printf("The value of *PTR2 =%d\n",*PTR2);

        if(PTR1==PTR2)
        {
            printf("Pointers holding same value");
        }
        else
        {
            printf("Pointers holding Different value");
        }
    }
            
        
Output:
             The value of x =5
             The value of y =6


             The value of *PTR1 =5
             The value of *PTR2 =6
             Pointers holding Different value
             --------------------------------
             Process exited after 0.04734 seconds with return value 32
             Press any key to continue . . .
                    
Example:4
4. Addition with pointer a constant value

    #include<stdio.h>

    int main()
    {
        int x=5;
        int *PTR1=&x;
        printf("The Address of x =%x\n",PTR1); // x stands for hexadecimal
        printf("The value of PTR1 =%x\n",*PTR1);
        PTR1=PTR1+1;
        printf("The Address of x =%x\n",PTR1);
        printf("The value of x =%x\n",*PTR1);

    }
  
        
Output:
             The Address of x =62fe14
             The value of PTR1 =5
             The Address of x =62fe18
             The value of x =62fe18

             --------------------------------
             Process exited after 0.04787 seconds with return value 23
             Press any key to continue . . .
        
Example:5
5.Addition with pointer a constant value
#include<stdio.h>
int main()
{
	int x = 5;
	int *PTR1 = &x;
	printf("The Address of x =%x\n", PTR1); // x stands for hexadecimal
	printf("The value of PTR1 =%x\n", *PTR1);
	*PTR1 = *PTR1 + 3;
	printf("The Address of x =%x\n", PTR1);
	printf("The value of x =%x\n", *PTR1);
}
Output:
The Address of x =62fe14
The value of PTR1 =5
The Address of x =62fe14
The value of x =8
Example:6
6.Addition with pointer a constant value.
#include<stdio.h>
int main()
{
	int x = 5;
	int *PTR1 = &x;
	printf("The value of PTR1 =%d\n", PTR1);
	printf("The value of PTR1 =%d\n", *PTR1);
	PTR1 = PTR1++; // post Increment
	*PTR1 = *PTR1 + 1;
	printf("The value of PTR1 =%d\n", PTR1);
	printf("The value of PTR1 =%d\n", *PTR1);
}
Output:
The value of PTR1 =6487572
The value of PTR1 =5
The value of PTR1 =6487572
The value of PTR1 =6
           
Example:7
Addition with pointer a constant value.
#include<stdio.h>
int main()
{
	int x = 5;
	int *PTR1 = &x;
	printf("The value of PTR1 =%u\n", PTR1);
	printf("The value of PTR1 =%d\n", *PTR1);
	++PTR1; // pre Increment
	*PTR1 = 6;
	printf("The value of PTR1 =%u\n", PTR1);
	printf("The value of PTR1 =%d\n", *PTR1);
}
Output:
The value of PTR1 =6487572
The value of PTR1 =5
The value of PTR1 =6
Example:8

    #include<stdio.h>

    int main()
    {
        int x=5;
        int *PTR1=&x;
        printf("The value of PTR1 =%d\n",PTR1);
        printf("The value of PTR1 =%d\n",*PTR1);
        //PTR1=PTR1/5;// WE CAN'T DIVIDE TWO POINTERS.

        printf("The value of PTR1 =%d\n",PTR1);
        printf("The value of PTR1 =%d\n",*PTR1);
    }
    
        
Output:
            The value of PTR1 =6487572
            The value of PTR1 =5
            The value of PTR1 =6487572
            The value of PTR1 =5

            --------------------------------
            Process exited after 0.05053 seconds with return value 0
            Press any key to continue . . .           
        
Example:9
9.POINTERS WITH ARRAY

     #include<stdio.h>

    int main()
    {
        int arr[15],size,i;
        int *PTR;
        printf("Enter the size of an array :\n");
        scanf("%d",&size);
        printf("Enter the %d elements in an array",size);
        PTR=arr;// THE FIRST ELEMENT'S ADDRESS GET STORED INTO PTR;
        for(i=0;i <size;i++)
        {
            scanf("%d",&arr[i]);
        }

            for(i=0;i <size;i++)
        {
        printf("The value in arr %d  :: The address in array %u\n",arr[i],&arr[i]);
        printf("The value in arr %d  :: The address in array %u\n\n",*PTR,PTR);
        PTR++;
        }
    }
    
      
Output:
                Enter the size of an array :
                5
                Enter the 5 elements in an array
                1
                2
                3
                4
                4
                The value in arr 1  :: The address in array 6487504
                The value in arr 1  :: The address in array 6487504

                The value in arr 2  :: The address in array 6487508
                The value in arr 2  :: The address in array 6487508

                The value in arr 3  :: The address in array 6487512
                The value in arr 3  :: The address in array 6487512

                The value in arr 4  :: The address in array 6487516
                The value in arr 4  :: The address in array 6487516

                The value in arr 4  :: The address in array 6487520
                The value in arr 4  :: The address in array 6487520


                --------------------------------
                Process exited after 4.452 seconds with return value 5
                Press any key to continue . . .
                  
      
Example:10
POINTERS WITH ARRAY

 #include<stdio.h>

    int main()
    {
        int arr[15],size,i;
        int *PTR;
        printf("Enter the size of an array :\n");
        scanf("%d",&size);
        printf("Enter the %d elements in an array",size);
        PTR=&arr[0];// CAN D0 LIKE THIS
    //  PTR=&arr[14];// THAN FIRST ELEMENTS ADDRESS GET STORED INTO PTR;
        for(i=0;i<size;i++)
        {
            scanf("%d",&arr[i]);
        }

            for(i=0;i<size;i++)
        {

  //  printf("The value in arra %d  :: The address in array %u\n",*PTR,PTR);
    printf("The value in arra %d  :: The address in array %u\n",arr[i],&arr[i]);
    printf("The value in arra %d  :: The address in array %u\n",i[arr],&i[arr]);
    printf("The value in arra %d  :: The address in array %u\n",*(PTR+i),(PTR+i));
    printf("The value in arra %d  :: The address in array %u\n\n",*(i+PTR),(i+PTR));
    PTR++;// WILL CHANGE THE MEMORY LOCATION
        }
    }
    
      
Output:
            Enter the size of an array :
            2
            Enter the 2 elements in an array
            3
            4
            The value in arra 3  :: The address in array 6487504
            The value in arra 3  :: The address in array 6487504
            The value in arra 3  :: The address in array 6487504
            The value in arra 3  :: The address in array 6487504

            The value in arra 4  :: The address in array 6487508
            The value in arra 4  :: The address in array 6487508
            The value in arra 1  :: The address in array 6487512
            The value in arra 1  :: The address in array 6487512


            --------------------------------
            Process exited after 5.269 seconds with return value 0
            Press any key to continue . . .