Pointers in C language

Pointers in C language

"Pointers" is a concept that most beginners consider it as rocket science. let's see what pointers are in c language.

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

let's say we have an integer variable "a" with a value of 20. And another variable p (pointer)stores the address of the variable "a".

void main() {
    int a,*p;
    a = 20;
    p = &a; // storing address of 'a' in 'p'
    printf("adress of a is : %d",p); //printing address
}
output:
adress of a is : 838153212

This means variable p has the address of a in it.

To print the value of the variable that p is pointing to, we need to use the '*' sign in front of the pointer variable.

#include <stdio.h>

void main() {
    int a,*p;
    a = 20;
    p = &a;
    printf("\nadress of a is : %d",p);
    printf("\nvalue of variable that p is pointing : %d",*p);
    //we use * in front of pointer to access the value in that address
}

Output:

adress of a is : 419453308
value of variable that p is pointing : 20

Types of Pointers in C

Pointers in C are strongly typed.

But why pointers are strongly typed when they just store the address?

Pointers in C are strongly typed because C recognizes memory locations with the help of the datatype given to the variable.

Let's say we have an int pointer: " *P "

where the size of " *p " is 4 bytes.

lets say *p = 1025;

Then in memory, it's stored as

00000000, 00000000, 00000100, 00000001 // binary representation in memory

4th byte, 3rd byte, 2nd byte , 1st byte // memory blocks

204, 203, 202, 201 //addresses in the memory

if we print the pointer p, we will get the value of the base address which is "201".

but if we print the value in pointer p i.e *p, then we will get the value: 1025.

A pointer can store only the base address of a variable, but while extracting the data from the memory, it will extract all the addresses of the given variable.

But how do the compilers identify all addresses of a variable?

It identifies the addresses of the variable with the data type given to that pointer.

In the above example, int has a size of 4 bytes, so it will understand that it should take values from 201 to 204 (4 bytes further).

That is why data types are required for the pointers in C language.

The syntax for pointers with different datatypes

#include<stdio.h>
void main(){
int a=20,*p1;
float f =20.5,*p2;
char c = 'P', *p3;
p1=&a;
p2=&f;
p3=&c;
printf("\n address of integer pointer : %d",p1);
printf("\n address of float pointer : %d",p2);
printf("\n address of Char pointer : %d",p3);

printf("\n pointing value of integer pointer : %d",*p1);
printf("\n pointing value of float pointer : %f",*p2);
printf("\n pointing value of Char pointer : %c",*p3);
}

Pointer to Pointer :

A variable that can store the address of a pointer.

pointer to pointer is denoted as **ptr.

program to demonstrate pointer to pointer:

#include<stdio.h>
void main(){
    int x =5;
    int *p;
    p = &x;
    //printf("\n value of *p : %d",*p);
    *p = 6;

    int **q; // this pointer is used to point another pointer
    q = &p;
    int ***r; //we can go on pointing like this.....
    r = &q;

    printf("\n value of x: %d ",x);
    printf("\n value of p: %d ",p);
    printf("\n value of q: %d ",q);
    printf("\n value of r: %d \n\n",r);

    printf("\n Address : ");
    printf("\n x Address : %d",&x);
    printf("\n p Address : %d",&p);
    printf("\n q Address : %d",&q);
    printf("\n r Address : %d",&r);

    printf("\n  ");
    printf("\n *p : %d",*p);
    printf("\n *q : %d",*q);
    printf("\n **q : %d",**q);
    printf("\n ***r : %d",***r);
}
Output: 
value of x: 6
 value of p: -285214788
 value of q: -285214800
 value of r: -285214808


 Address :
 x Address : -285214788
 p Address : -285214800
 q Address : -285214808
 r Address : -285214816

 *p : 6
 *q : -285214788
 **q : 6
 ***r : 6

Note 1: the output of my code will be not the same as yours because addresses will differ from computer to computer.

Note 2: Your variable addresses will change as you execute your code n times. so even for this case, your out output will be not the same as you execute your code n times.

Pointers and Arrays

let's see how we can access array elements using pointers.

lets say we have a 1D array: a[10]

if we print the variable " a " --> printf("\n %d" , a);

we will get the address of the first element of the array.

code:

#include<stdio.h>
void main(){
    int a[10][10];
    printf("\n address of a :  %d",a);
    printf("\n address of a[0] :  %d",&a[0]);
}
Output:
address of a :  836107840
address of a[0] :  836107840

This output says that "a" is a pointer that stores the address of the first element in the array.

Printing elements in an Array using pointers

As we discussed above we can access the address of an array by directly printing its name, since it is a pointer.

Now to get the value in that address we can use * in front of it.

By adding 1 to the address of the first element, we can iterate through the array.

adding 1 to the address will result in moving to the next four bytes in the array because each integer is of size 4 bytes.

#include<stdio.h>
void main(){
    int i,n;
    int a[]={1,3,6,9,13};
    n = sizeof(a)/sizeof(a[0]);

    for ( i = 0; i < n; i++)
    {
        printf("\n Element at %d index : %d",i,*(a+i));
    }

}
 Element at 0 index : 1
 Element at 1 index : 3
 Element at 2 index : 6
 Element at 3 index : 9
 Element at 4 index : 13