C Pointers
C Pointers
Pointers are one of the core components of the C programming language. A pointer
can be used to store the memory address of other variables, functions, or even
other pointers. The use of pointers allows low-level memory access, dynamic
memory allocation, and many other functionality in C.
What is a Pointer in C?
A pointer is defined as a derived data type that can store the address of other C
variables or a memory location. We can access and manipulate the data stored in
that memory location using pointers.
Syntax of C Pointers
The syntax of pointers is similar to the variable declaration in C, but we use the ( *
) dereferencing operator in the pointer declaration.
datatype * ptr;
where
• ptr is the name of the pointer.
• datatype is the type of data it is pointing to.
The above syntax is used to define a pointer to a variable. We can also define
pointers to functions, structures, etc.
Dereferencing a Pointer in C
C Pointer Arithmetic
Pointer Arithmetic is the set of valid arithmetic operations that can be performed
on pointers. The pointer variables store the memory address of another variable. It
doesn’t store any value.
Hence, there are only a few operations that are allowed to perform on Pointers in
C language. The C pointer arithmetic operations are slightly different from the ones
that we generally use for mathematical calculations. These operations are:
1. Increment/Decrement of a Pointer
2. Addition of integer to a pointer
3. Subtraction of integer to a pointer
4. Subtracting two pointers of the same type
5. Comparison of pointers
1. Increment/Decrement of a Pointer
Increment: It is a condition that also comes under addition. When a pointer is
incremented, it actually increments by the number equal to the size of the data
type for which it is a pointer.
For Example:
If an integer pointer that stores address 1000 is incremented, then it will
increment by 4(size of an int), and the new address will point to 1004. While if a
float type pointer is incremented then it will increment by 4(size of a float) and
the new address will be 1004.
Decrement: It is a condition that also comes under subtraction. When a pointer is
decremented, it actually decrements by the number equal to the size of the data
type for which it is a pointer.
ForExample:
If an integer pointer that stores address 1000 is decremented, then it will
decrement by 4(size of an int), and the new address will point to 996. While if a
float type pointer is decremented then it will decrement by 4(size of a float) and
the new address will be 996.
Note: It is assumed here that the architecture is 64-bit and all the data types are
sized accordingly. For example, integer is of 4 bytes.
5. Comparison of Pointers
We can compare the two pointers by using the comparison operators in C. We can
implement this by using all operators in C >, >=, <, <=, ==, !=. It returns true for the
valid condition and returns false for the unsatisfied condition.
1. Step 1: Initialize the integer values and point these integer values to the
pointer.
2. Step 2: Now, check the condition by using comparison or relational
operators on pointer variables.
3. Step 3: Display the output.
The following figure shows the pointer p and ptr. The darker arrow denotes a
pointer to an array.
Since memory in a computer is organized linearly it is not possible to store the 2-D
array in rows and columns. The concept of rows and columns is only theoretical,
actually, a 2-D array is stored in row-major order i.e rows are placed next to each
other. The following figure shows how the above 2-D array will be stored in memory.
We know that the name of an array is a constant pointer that points to 0th 1-D array
and contains address 5000. Since arr is a ‘pointer to an array of 4 integers’,
according to pointer arithmetic the expression arr + 1 will represent the address
5016 and expression arr + 2 will represent address 5032.
So we can say that arr points to the 0th 1-D array, arr + 1 points to the 1st 1-D array
and arr + 2 points to the 2nd 1-D array.
In general we can write:
arr + i Points to ith element of arr ->
Points to ith 1-D array
• Since arr + i points to ith element of arr, on dereferencing it will get
ith element of arr which is of course a 1-D array. Thus the expression *(arr +
i) gives us the base address of ith 1-D array.
• We know, the pointer expression *(arr + i) is equivalent to the subscript
expression arr[i]. So *(arr + i) which is same as arr[i] gives us the base
address of ith 1-D array.
• To access an individual element of our 2-D array, we should be able to
access any jth element of ith 1-D array.
• Since the base type of *(arr + i) is int and it contains the address of
0th element of ith 1-D array, we can get the addresses of subsequent
elements in the ith 1-D array by adding integer values to *(arr + i).
• For example *(arr + i) + 1 will represent the address of 1st element of
1stelement of ith 1-D array and *(arr+i)+2 will represent the address of
2nd element of ith 1-D array.
• Similarly *(arr + i) + j will represent the address of jth element of ith 1-D
array. On dereferencing this expression we can get the jth element of the
ith 1-D array.
Advantages of Pointers
Following are the major advantages of pointers in C:
• Pointers are used for dynamic memory allocation and deallocation.
• An Array or a structure can be accessed efficiently with pointers
• Pointers are useful for accessing memory locations.
• Pointers are used to form complex data structures such as linked lists,
graphs, trees, etc.
• Pointers reduce the length of the program and its execution time as well.
Disadvantages of Pointers
Pointers are vulnerable to errors and have following disadvantages:
• Memory corruption can occur if an incorrect value is provided to pointers.
• Pointers are a little bit complex to understand.
• Pointers are majorly responsible for memory leaks in C.
• Pointers are comparatively slower than variables in C.
• Uninitialized pointers might cause a segmentation fault.