C language Pointers

In this chapter we shall study about following
1. Introduction
2. Usage of Pointers
3. Pointer Introduction:
4. Pointer declaration:
5. Void pointers
6. Wild pointers
7. Pointers and arrays
8. Pointers to pointers

1. Introduction:

One of the most important and scary topic in C language is the pointers topic. Hence we shall understand them one topic at a time. By the time you complete this chapter, you will be comfortable with C pointers. If any doubts, please leave a comment below.

2. Usage of Pointers

1. Pointers are used to save memory.
2. They are used in data structures so that execution time is faster.
3. Pointers are used in file handling.
4. Pointers are used in dynamic memory allocation.
5. Pointers can be used to access array elements.
Note: Pointers in C are very powerful. If tried to access invalid memory the program will crash. Hence should take an extra step while dealing with pointers.

3. Pointer Introduction:

A pointer is a normal variable that is used to hold address of another variable.
As we know from previous chapters, a variable name is the name given to the memory location. Hence, a pointer will hold that memory location as it’s value.

4. Pointer declaration:

While dealing with pointers we come across 2 important signs. “*” and “&”.
“*” is called as indirection operator. It can be used in 2 different ways.
1. It is used to declare a pointer variable.
2. It is used to dereference the value from the address it is stored. Hence the name indirection.
“&” is used to get the address of the variable.
The space occupied by a pointer variable will always be 4 bytes.

Example: Below example shall explain in details

#include<stdio.h>

int main()
{
	// a simple variable
	int var = 10;

	// a pointer vaiable. Here "*" is used to declare a pointer variable.
	int *ptr = NULL; 

	// assgining the address of "var" with the help of "&" operator
	// now "ptr" will have the address of variable "var"
	ptr = &var;

	// while printing address we should use "%u", as unsigned integers
	printf("\nThe address of variable var = %u. \n", &var);

	printf("The value stored in ptr = %u. Notice that the address is same.\n", ptr);

	printf("The value of var = %d. \n", var);

	printf("The value  of var using ptr = %d. Here * is used as an indirection operator.\n", *ptr);

	// if we want to change the value of var using pointer, can be done as shown below

	*ptr = 20;
	printf("The value of var after changing = %d. \n", var);


	return 0;
}

Output:

The address of variable var = 3796290280.
The value stored in ptr = 3796290280. Notice that the address is same.
The value of var = 10.
The value  of var using ptr = 10. Here * is used as an indirection operator.
The value of var after changing = 20.

Example 2: To show that * operator can be used on normal variables also.

#include<stdio.h>

int main()
{
	int var = 10;

	printf("The value printed using * is = %d\n", *(&var) );


/* what does *(&var) means.
 *	as we know & is used for getting the address.
 *	"*" can be used as an indirection operator, to get the value stored in that address.
 *
 *	It can be visualized as below:
 *	
 *	*(value at address of var)
 *	output = value 
 */

	return 0;
}

Output:

The value printed using * is = 10

5. Void pointers

From first we know that every variable should be associated with a type. But sometimes while using pointers, we don’t know the type. We can assign the type of that pointer by using typecasting.
A point to be noted is that, until we typecast the pointer we will not be able to dereference the value.
Let us understand why the type of a pointer is necessary?
As we understood before, the size of a pointer is 4 bytes regardless of data type. But while dereferencing from the address, the pointer will look at the data type and then try to access those many bytes.
For example:
For an integer data type it will derefer 4 bytes.
For a short data type it will derefer 2 bytes.
For char data type it will derefer 1 byte.
Hence typecasting is necessary for void pointers.

Example: Below is the example:

#include<stdio.h>

int main()
{
	void *vPtr = NULL;

	int iNum = 10;
	float fNum = 10.23;

	vPtr = &iNum;
	printf("The value of iNum using pointer = %d\n", *(int*)vPtr );

	*(int *) vPtr = 20;
	printf("The value of iNum after changing pointer = %d\n", *(int*)vPtr );



	vPtr = &fNum;
	printf("The value of fNum using pointer = %f\n", *(float*)vPtr );

	*(float *) vPtr = 23.45;
	printf("The value of ifNum after changing pointer = %f\n", *(float*)vPtr );


	return 0;
}

Output:

The value of iNum using pointer = 10
The value of iNum after changing pointer = 20
The value of fNum using pointer = 10.230000
The value of ifNum after changing pointer = 23.450001

6. Wild pointers

As we have seen in the above programs, a pointer when declared, should be initialized with NULL. Else it will hold garbage value. Those kind of pointers are called as wild pointers.

7. Pointers and arrays

In the previous chapter we have learned about arrays. In-fact internally array is a pointer, that points to the first element of the array. All the array elements are stored continuously. Hence we can use pointers to access the array members.
An array is represented as
arr[10]
Here we have declared an pointer arr pointing to first variable. i.e. internally it will be &arr[0]. Hence when we access arr[1] internally it will be converted into *(arr + 1).
In general arr[i] will be *(arr + i).

Example: Below program shows different ways to access the array elements.

#include<stdio.h>


int main()
{
	int arr[] = {1, 2, 3, 4, 5};

	printf("arr[i]		*(arr + i)		*(i + arr)		i[arr]		address using (arr+i)\n");

	for (int i = 0; i < 5; ++i)
	{
		printf("%d		%d			%d			%d		%u\n", arr[i], *(arr + i), *(i + arr), i[arr], arr+i );
	}

	return 0;
}

Output:

arr[i]		*(arr + i)		*(i + arr)		i[arr]		address using (arr+i)
1		1			1			1		3853433552
2		2			2			2		3853433556
3		3			3			3		3853433560
4		4			4			4		3853433564
5		5			5			5		3853433568

8. Pointers to pointers

As a pointer is a variable that holds the address of another variable. What do you call a variable that holds the address of another pointer? That’s right, pointer to pointer.
A pointer variable holding the address of another pointer is called as pointer to pointer.
It is declared using 2 stars “int **ptr = NULL;”

Example: Example to show the pointer to pointer access

#include<stdio.h>

int main()
{
	int iNum = 1234;
	int *ptr = &iNum;
	int **pptr = &ptr;


	printf("The address of iNum is = %u\n", &iNum ); 
	printf("The address of iNum using pointer %u\n", ptr ); 

	/*
	 * as pointer ptr is holding the address of variable iNum
	 * so while using pointer to pointer we have the address of "ptr".
	 * But to get the value stored inside pointer ptr, we shall access with *ptr
	 */
	printf("The address of iNum using pointer to pointer %u\n", *pptr ); 

	printf("===============================================\n"); 

	printf("The value of iNum is = %d\n", iNum ); 
	printf("The value of iNum using pointer is = %d\n", *ptr ); 
	printf("The value of iNum using pointer to pointer is =	 %d\n", **pptr ); 


	return 0;
}

Output:

The address of iNum is = 3982359272
The address of iNum using pointer 3982359272
The address of iNum using pointer to pointer 3982359272
===============================================
The value of iNum is = 1234
The value of iNum using pointer is = 1234
The value of iNum using pointer to pointer is =	 1234
Write a Comment

Leave a Comment

Your email address will not be published. Required fields are marked *