Pointers in C

What are Pointers?

Pointer is a variable that points to an address of a value.

Pointer => address that contains the value

 

Symbols used in pointer :

& (ampersand sign) : ‘Address of operator’. It determines the address of a variable.

* (asterisk sign) : indirection operator / value at address. Accesses the value at the address.

Example :

 int i = 3 ;

This declaration tells the C compiler to :-

  • Reserve space in memory to hold the integer value.
  • Associate the name i with this memory location.
  • Store the value 3 at this location.

We may represent the location of i in the memory by :-

 

  • The computer has selected memory location 65524 as the place to store the value 3.
  • The location number 65524 is not a number to be relied upon, because some other time the computer may choose a different location for storing the value 3.
  • The important point is, i’s address in memory is a number.

Example :

    #include <stdio.h>
    #include <conio.h>

    void main()
    {
    int i = 3 ;
    printf ( "\nAddress of i = %u", &i);
    printf ( "\nValue of i = %d", i);
    printf ( "\nValue of i = %d", *(&i));
    }

Output :

Address of i = 65524
Value of i = 3

Explanation :

  • The pointer points to the address 65524 of variable i, that contains the value of i i.e 3
  • Pointer points to ->65524 address that points to =>value 3
  • &i gives the address of the variable i.
  • *i gives the value store at the address of i.
  • ‘&’ => ‘address of ’ operator.
  • The expression &i in the first printf() statement returns the address of the variable i, which in this case happens to be 65524.
  • As 65524 is an address, there is no sign associated with it. So to print the address we use ‘%u’ which is a format specifier for printing an unsigned integer.
  • The another pointer operator is ‘*’ called ‘value at address’ operator which gives the value stored at a particular address.
  • The ‘value at address’ operator is also called ‘indirection’ operator.
  • *(&i) is same as printing the value of i.

Declaring a Pointer

Syntax :

    datatype *variable_name; //pointer to datatype

Example :

    int *j; //pointer to integer
    • This means the value at the address contained in j is an int.
    • This declaration tells the compiler that j will be used to store the address of an integer value.
    • The j is called as pointer variable. This variables are capable of holding addresses.

These addresses can be collected in a variable

j = &i ;

  • The variable j is called pointer variable that stores the address of i i.e 65524
  • j(contains the address of i) points to -> the address of i , this points to => the value of i i.e 3but the address of j is 65522.
    #include <stdio.h>
    #include <conio.h>
    void main()
    {
    int i = 3;
    // store the address of an integer value
    int *j;

    clrscr();

    //stores the address of i variable
    j=&i;
    printf("Address of i variable is %x \n",&i);
    printf("Address of j variable is %x \n",j);
    printf("Value of j variable is %d \n",*j);

    getch();
    }

Output :

Address of i variable is 65524
Address of j variable is 65522
Value of j variable is 3

The Expression *j will give the value of i i.e 3
As * stands for ‘value at address’. Means the j contains the address of variable i, so *j will give the value stored at that address which is there in j (i.e 65524 address contains value 3).

 

Ways to declare Pointers

    int *i;
    char *ch;
    float *f;
  • Here, ich and f are declared as pointer variables, i.e.variables capable of holding addresses.
  • Remember that, addresses are always going to be whole numbers, therefore pointers always contain whole numbers.
  • Now we can put these two facts together and say that the pointers are variables that contain addresses, and since addresses are always whole numbers, pointers would always contain whole numbers.
  • The declaration float *f does not mean that f is going to contain a floating-point value. What it means is, f is going to contain the address of a floating-point value.
  • Similarly, char *ch means that ch is going to contain the address of a char value.

Pointer to Pointer

Pointer is a variable that contains address of another variable. Now this variable itself might be another pointer. Thus, we now have a pointer that contains another pointer’s address.

Example :

    #include <stdio.h>
    #include <conio.h>
    void main()
    {
    int i = 3, *j, **k ;
    j = &i ;
    k = &j ;

    printf ( "\nAddress of i = %u", &i ) ;
    printf ( "\nAddress of i = %u", j ) ;
    printf ( "\nAddress of i = %u", *k ) ;
    printf ( "\nAddress of j = %u", &j ) ;
    printf ( "\nAddress of j = %u", k ) ;
    printf ( "\nAddress of k = %u", &k ) ;
    printf ( "\nValue of j = %u", j ) ;
    printf ( "\nValue of k = %u", k ) ;
    printf ( "\nValue of i = %d", i ) ;
    printf ( "\nValue of i = %d", * ( &i ) ) ;
    printf ( "\nValue of i = %d", *j ) ;
    printf ( "\nValue of i = %d", **k ) ;
    }

Output :

Address of i = 65524
Address of i = 65524
Address of i = 65524
Address of j = 65522
Address of j = 65522
Address of k = 65520
Value of j = 65524
Value of k = 65522

Explanation :

Here the declarations as follows :

    int i = 3; //i is an ordinary int,
    int *j; //j is a pointer to an int
    int **k; //k is a pointer to an integer pointer

Now initializations as follow :

    j = &i ; //address of variable i is stored in j
    k = &j ;//address of variable j is stored in k

printf (“\nAddress of k = %u”, &k); will return address of k.

printf (“\nAddress of j = %u”, k); will return value of k or address of j.

printf (“\nAddress of i = %u”, *k); will return the address of i.

*k = *(&j)=>*(65522) will return value stored at this address of the variable j i.e 65524 = 65524

printf (“\nValue of i = %d”, **k); will return the value of i.

**k = **(&j)=>[*(&j)] will give the value stored at the address of variable j i.e 65524 which is the address of variable ii.e &i.

= *(&i) will give value stored at the address of variable i i.e 3.

 

Pointer Arithmetic

The pointer holds address of a value, so there can be arithmetic operations on the pointer variable.

Arithmetic operations possible on pointer in C language :

  • Increment.
  • ecrement.
  • Addition.
  • Subtraction.

 

Increment :

  • Incrementing a pointer is used in array because it is contiguous memory location.
  • Increment operation depends on the data type of the pointer variable.

The formula of incrementing pointer is given below :

    new_address= current_address + i * size_of(data type)

Example :

Incrementing pointer variable on 64 bit OS

    #include <stdio.h>
    #include <conio.h>
    void main()
    {
    int i = 3;
    int *j;//pointer to int

    j = &i;//stores the address of i variable
    printf("Address of i variable is %u \n", j);

    j = j+1; // incrementing pointer by 1(4 bytes)
    printf("After increment: Address of i variable is %u \n",j);
    }

Output :

Address of i variable is 65524
After increment: Address of i variable is 65528
Explanation :
For 32 bit int variable, it will increment to 2 byte.
For 64 bit int variable, it will increment to 4 byte.

Decrement :

The formula of decrementing pointer is given below :

    new_address= current_address - i * size_of(data type)

Example :

    #include <stdio.h>
    #include <conio.h>
    void main()
    {
    int i = 3;
    int *j;//pointer to int

    j = &i;//stores the address of i variable
    printf("Address of i variable is %u \n",j);

    j = j - 1; //decrementing pointer by 1(4 bytes)
    printf("After decrement: Address of i variable is %u \n",j);
    }

Output :

Address of i variable is 65524
After decrement: Address of i variable is 65520

Pointer Addition

We can add a value to the pointer variable.

The formula of adding value to pointer is given below :

    new_address= current_address + (value * size_of(data type))

Example :

    #include <stdio.h>
    #include <conio.h>
    void main()
    {
    int i = 3;
    int *j;//pointer to int

    j = &i;//stores the address of i variable
    printf("Address of i variable is %u \n", j);

    j = j+3; // incrementing pointer by 4*3=12 bytes
    printf("After increment: Address of i variable is %u \n",j);
    }

Output :

Address of i variable is 65524
After increment: Address of i variable is 65536

Explanation :

For 32 bit int variable, it will add 2 * number.
For 64 bit int variable, it will add 4 * number.

Pointer Subtraction

Like pointer addition, we can subtract a value from the pointer variable.

The formula of subtracting value from pointer variable is given below :

    new_address= current_address - (value * size_of(data type))

Example :

    #include <stdio.h>
    #include <conio.h>
    void main()
    {
    int i = 3;
    int *j;//pointer to int

    j = &i;//stores the address of i variable
    printf("Address of i variable is %u \n", j);

    j = j - 3; // decrementing pointer by 4*3=12 bytes
    printf("After increment: Address of i variable is %u \n",j);
    }

Output :

Address of i variable is 65524
After increment: Address of i variable is 65512