- C Programming Tutorial
- C - Home
- C - Overview
- C - Features
- C - History
- C - Environment Setup
- C - Program Structure
- C - Hello World
- C - Compilation Process
- C - Comments
- C - Tokens
- C - Keywords
- C - Identifiers
- C - User Input
- C - Basic Syntax
- C - Data Types
- C - Variables
- C - Integer Promotions
- C - Constants
- C - Literals
- C - Escape sequences
- C - Storage Classes
- C - Operators
- C - Decision Making
- C - Loops
- C - While loop
- C - Functions
- C - Main Functions
- C - Return Statement
- C - Scope Rules
- C - Arrays
- C - Properties of Array
- C - Multi-Dimensional Arrays
- C - Passing Arrays to Function
- C - Return Array from Function
- C - Variable Length Arrays
- C - Pointers
- C - Pointer Arithmetics
- C - Passing Pointers to Functions
- C - Strings
- C - Array of Strings
- C - Structures
- C - Structures and Functions
- C - Arrays of Structures
- C - Pointers to Structures
- C - Self-Referential Structures
- C - Nested Structures
- C - Unions
- C - Bit Fields
- C - Typedef
- C - Input & Output
- C - File I/O
- C - Preprocessors
- C - Header Files
- C - Type Casting
- C - Error Handling
- C - Recursion
- C - Variable Arguments
- C - Memory Management
- C - Command Line Arguments
- C Programming Resources
- C - Questions & Answers
- C - Quick Guide
- C - Useful Resources
- C - Discussion
C - Pointer arithmetic
A pointer variable in C stores the address of another variable. The address is always an integer. So, can we perform arithmetic operations such as addition, subtraction etc. on the pointers? In this chapter, we discuss which arithmetic operators use pointers in C as operands, and which operations are not defined to be performed with pointers.
Increment/decrement operators
We know that the symbols ++ and -- are defined as increment and decrement operators in C. They are unary operators, used in prefix or postfix manner with numeric variable operands, and increment or decrement the value of the variable by one.
Assume that an integer variable x is created at address 1000 in the memory, with 10 as its value. The x++ statement makes x as 11.
int x = 10; //created at address 1000 x++; // x becomes 11
What happens if we declare y as pointer to x and increment y by 1 (with y++)? Assume that the address of y itself is 2000.
int x = 10; //created at address 1000 int *y = &x ; // y is created at address 2000 and holds 1000 – address of x y++; //y becomes 1004
Since the variable y stores 1000 (the address of x), we expect it to become 1001 because of ++ operator, but increment by 4, which is the size of int variable.
The reason behind this is, if address of x 1000, it occupies 4 bytes 1000, 1001, 1002 and 1003. Hence, the next integer can be put only in 1004 and not before it. Hence y the pointer to x becomes 1004 when incremented.
Example
Let us see the realistic example −
#include <stdio.h> int main(){ int x = 10; int *y = &x; printf("value of y before increment: %d\n", y); y++; printf("value of y after increment: %d", y); }
Output
value of y before increment: 6422036 value of y after increment: 6422040
You can see that the value has increased by 4.
Similarly, the -- operator decrements the value by the size of the data type. Let us change the types of x and y to double and float * and see the effect of decrement operator.
Example
#include <stdio.h> int main(){ double x = 10; double *y = &x; printf("value of y before decrement: %ld\n", y); y--; printf("value of y after decrement: %ld", y); }
Output
value of y before decrement: 6422032 value of y after decrement: 6422024
When an array is declared, the elements are stored in adjacent memory locations. In case of int array, each array subscript is placed apart by 4 bytes, as the following figure shows −
Hence, if a variable stores the address of 0th element of the array, increment takes it to the 1st element. Likewise, we can traverse the array by incrementing the pointer successively.
Example
#include <stdio.h> int main(){ int a[]= {10, 20, 30, 40, 50, 60, 70, 80, 90, 100}; int len = sizeof(a)/sizeof(int); int *x = a; int i = 0; for (i=0; i<len; i++){ printf("Address of subscript %d = %d Value = %d\n", i, x, *x); x++; } return 0; }
Output
Address of subscript 0 = 6421984 Value = 10 Address of subscript 1 = 6421988 Value = 20 Address of subscript 2 = 6421992 Value = 30 Address of subscript 3 = 6421996 Value = 40 Address of subscript 4 = 6422000 Value = 50 Address of subscript 5 = 6422004 Value = 60 Address of subscript 6 = 6422008 Value = 70 Address of subscript 7 = 6422012 Value = 80 Address of subscript 8 = 6422016 Value = 90 Address of subscript 9 = 6422020 Value = 100
Addition/subtraction of pointers
We are familiar with + and − operators when used with normal numeric operands. When used with pointers, their behaviour is a little different.
Since the pointers are fairly large integers (especially in modern 64 bit systems), addition of two pointers is meaningless. When we add a 1 to a pointer, it points to next location where an integer may be stored. Obviously, when we add a pointer (itself a large integer), the location it points, may not be in the memory layout.
However, subtraction of two pointers is realistic. It returns the number of data types that can fit in the two pointers.
Let us the array in the previous example, and perform the subtraction of pointers of a[0] and a[9]
Example
#include <stdio.h> int main(){ int a[]= {10, 20, 30, 40, 50, 60, 70, 80, 90, 100}; int *x = &a[0]; //zeroth element int *y = &a[9]; //last element printf("Add of a[0]: %ld add of a[9]: %ld\n", x, y); printf("subtraction of two pointers: %ld", y-x); }
Output
Add of a[0]: 140729162482768 add of a[9]: 140729162482804 subtraction of two pointers: 9
It can be seen that the numerical difference between the two integers is 36, it tells that the subtraction is 9, because it can accommodate 9 integers between the two pointers.
Pointer Comparisons
Pointers may be compared by using relational operators, such as ==, <, and >. If p1 and p2 point to variables that are related to each other, such as elements of the same array, then p1 and p2 can be meaningfully compared.
The following program modifies the previous example − one by incrementing the variable pointer so long as the address to which it points is either less than or equal to the address of the last element of the array, which is &var[MAX − 1]
Example
#include <stdio.h> const int MAX = 3; int main () { int var[] = {10, 100, 200}; int i, *ptr; /* let us have address of the first element in pointer */ ptr = var; i = 0; while ( ptr <= &var[MAX - 1] ) { printf("Address of var[%d] = %d\n", i, ptr ); printf("Value of var[%d] = %d\n", i, *ptr ); /* point to the previous location */ ptr++; i++; } return 0; }
Output
Address of var[0] = 6422020 Value of var[0] = 10 Address of var[1] = 6422024 Value of var[1] = 100 Address of var[2] = 6422028 Value of var[2] = 200