Last updated on September 24, 2020
You should know by now that a pointer is nothing more than a variable used to store a memory address. If this is still news to you then go back and readPointer Basics before continuing with this chapter.
In this chapter, we will discuss arithmetic operations that can be performed on pointers.
We can't perform every type of arithmetic operations with pointers. Pointer arithmetic is slightly different from arithmetic we normally use in our daily life. The only valid arithmetic operations applicable on pointers are:
The pointer arithmetic is performed relative to the base type of the pointer. For example, if we have an integer pointerip which contains address1000, then on incrementing it by1, we will get1004 (i.e1000 + 1 * 4) instead of1001 because the size of theint data type is4 bytes. If we had been using a system where the size ofint is2 bytes then we would get1002 ( i.e1000 + 1 * 2 ).
Similarly, on decrementing it we will get996 (i.e1000 - 1 * 4) instead of999.
So, the expressionip + 4 will point to the address1016 (i.e1000 + 4 * 4 ).
Let's take some more examples.
123 | inti=12,*ip=&i;doubled=2.3,*dp=&d;charch='a',*cp=&ch; |
Suppose the address ofi,d andch are1000,2000,3000 respectively, thereforeip,dp andcp are at1000,2000,3000 initially.
| Pointer Expression | How it is evaluated ? |
|---|---|
ip = ip + 1 | ip =>ip + 1 =>1000 + 1*4 =>1004 |
ip++ or++ip | ip++ =>ip + 1 =>1004 + 1*4 =>1008 |
ip = ip + 5 | ip =>ip + 5 =>1008 + 5*4 =>1028 |
ip = ip - 2 | ip =>ip - 2 =>1028 - 2*4 =>1020 |
ip-- or--ip | ip =>ip + 2 =>1020 + 2*4 =>1028 |
| Pointer Expression | How it is evaluated ? |
|---|---|
dp + 1 | dp = dp + 1 =>2000 + 1*8 =>2008 |
dp++ or++dp | dp++ =>dp+1 =>2008+1*8 =>2016 |
dp = dp + 5 | dp =>dp + 5 =>2016+5*8 =>2056 |
dp = dp - 2 | dp =>dp - 2 =>2056-2*8 =>2040 |
dp-- or--dp | dp => dp - 1=>2040-1*8=>2032` |
| Pointer Expression | How it is evaluated ? |
|---|---|
cp + 1 | cp = cp + 1 =>3000 + 1*1 =>3001 |
cp++ or++cp | cp =>cp + 1 =>3001 + 1*1 =>3002 |
cp = cp + 5 | cp =>cp + 5 =>3002 + 5*1 =>3007 |
cp = cp - 2 | cp =>cp + 5 =>3007 - 2*1 =>3005 |
cp-- or--cp | cp =>cp + 2 =>3005 - 1*1 =>3004 |
Note: When we increment or decrement pointer variables using pointer arithmetic then, the address of variablesi ,d ,ch are not affected in any way.
Arithmetic operation on typechar seems like ordinary arithmetic because the size ofchar type is1 byte. Another important point to note is that when we increment and decrement pointer variable by adding or subtracting numbers then it is not necessary that the pointer variable still points to a valid memory location. So, we must always pay special attention when we move the pointer in this way. Generally, we use pointer arithmetic with arrays because elements of an array are arranged in contiguous memory locations, which is discussed in detail in the next chapter.
The following program shows pointer arithmetic.
1 2 3 4 5 6 7 8 910111213141516171819202122 | #include<stdio.h>intmain(){inti=12,*ip=&i;doubled=2.3,*dp=&d;charch='a',*cp=&ch;printf("Value of ip = %u\n",ip);printf("Value of dp = %u\n",dp);printf("Value of cp = %u\n\n",cp);printf("Value of ip + 1 = %u\n",ip+1);printf("Value of dp + 1 = %u\n",dp+1);printf("Value of cp + 1 = %u\n\n",cp+1);printf("Value of ip + 2 = %u\n",ip+2);printf("Value of dp + 2 = %u\n",dp+2);printf("Value of cp + 2 = %u\n",cp+2);return0;} |
Expected Output:
1 2 3 4 5 6 7 8 91011 | Value of ip = 2293316Value of dp = 2293304Value of cp = 2293303Value of ip + 1 = 2293320Value of dp + 1 = 2293312Value of cp + 1 = 2293304Value of ip + 2 = 2293324Value of dp + 2 = 2293320Value of cp + 2 = 2293305 |
If we have two pointersp1 andp2 of base type pointer toint with addresses1000 and1016 respectively, thenp2 - p1 will give4, since the size ofint type is4 bytes. If you subtractp2 fromp1 i.ep1 - p2 then the answer will be negative i.e-4.
The following program demonstrates pointer arithmetic between two pointers of the same type.
1 2 3 4 5 6 7 8 910111213141516 | #include<stdio.h>intmain(){inti1=12,*ip1=&i1;inti2=12,*ip2=&i2;printf("Value of ip1 or address of i1 = %u\n",ip1);printf("Value of ip2 or address of i2 = %u\n\n",ip2);printf("ip2 - ip1 = %d\n",ip1-ip2);printf("ip1 - ip2 = %d\n",ip2-ip1);// signal to operating system program ran finereturn0;} |
Expected Output:
12345 | Value of ip1 or address of i1 = 2686788Value of ip2 or address of i2 = 2686780ip2 - ip1 = 2ip1 - ip2 = -2 |
While processing elements of an array (as you will see in the next chapter) C programmers often mix indirection operator (*) and increment/decrement operator(++ and-- ).
Always remember that the precedence of indirection operator (*) and increment/decrement operator are same and they associate from right to left (seeOperator Precedence and Associativity in C).
Supposex is integer variable andp is a pointer toint. Now consider the following statements and try to interpret them.
Example 1:
x=*p++;
Since* and++ operators have the same precedence and associate from right to left++ will be applied top, not to*p. Because the increment operator is postfix, so first the value ofp is used in the expression then it will be incremented. Therefore, the first integer pointed byp will be dereferenced and assigned tox, then the value ofp will be incremented by1.
Example 2:
x=++*p;
Here* operator will be first applied top then++ will be applied to*p. Therefore first integer pointer is dereferenced, the value obtained from dereferencing is incremented and eventually assigned tox.
Example 3:
x=*++p;
The++ operator is prefixed, so first,p will be incremented, then the value at the new address is dereferenced and assigned tox.
Note: If you still have any confusion, you can always use() around expression which you want to evaluate first.
You can use relational operators (<,<=,>,>= ,== ,!=) with pointers. The== and!=operators are used to compare two pointers whether they contain the same address or not. Two pointers are equal when they both are null, or contains the address of the same variable. Use of these (i.e== and!=) operators are valid only when pointers are of the same base type, or between a null pointer and any other pointer, or void pointer(will be discussed later) and any other pointer. Use of other relational operators (<,<=,>,>=) to compare two pointers is meaningful only when they both point to the elements of the same array.
As we know the pointer is a variable that contains the memory address. The pointer variable itself occupies some space in memory and hence it also has a memory address. We can store the address of the pointer variable in some other variable, which is known as pointer to pointer. The syntax of declaring a pointer to a pointer is as follows:
Syntax:data_type **p;
Let's take an example:
123 | inti=10;int*ip=&i;int**iip=&ip; |
Hereip is of type(int *) or pointer toint,iip is of type(int **) or pointer to pointer toint.

We know that*ip will give value at addressip i.e value ofi. Can you guess what value will**iip will return?
**iip
We know that the indirection operator evaluated from right to left so**iip can also be written as
*(*iip)
*iip means value at addressiip or address stored atip. On dereferencing the address stored atip we will get the value stored in the variablei.
123 | *(*iip)=> *ip=> i |
Therefore**iip gives the value stored in the variablei.
The following program demonstrates how to use pointer to pointer inint.
1 2 3 4 5 6 7 8 9101112131415161718192021 | #include<stdio.h>intmain(){inti=10;int*ip=&i;int**iip=&ip;printf("Value of i = %d\n\n",i);printf("Address of i = %u\n",&i);printf("Value of ip = %d\n\n",ip);printf("Address of ip = %u\n",&ip);printf("Value of iip = %d\n\n",iip);printf("Value of *iip = value of ip = %d\n",*iip);printf("Value of **iip = value of i = %d\n\n",**iip);return0;} |
Expected Output:
1 2 3 4 5 6 7 8 910 | Value of i = 10Address of i = 2293332Value of ip = 2293332Address of ip = 2293320Value of iip = 2293320Value of *iip = value of ip = 2293332Value of **iip = value of i = 10 |