# 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".

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

```bash
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.

```c
#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:

```bash
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

```c
#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:**

```c
#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);
}
```

```bash
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 " --&gt; printf("\\n %d" , a);

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

**code**:

```bash
#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]);
}
```

```bash
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 *<mark>moving to the next four bytes</mark>* in the array because each integer is of size 4 bytes.

```c
#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));
    }
    
}
```

```bash
 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
```
