what is pointer in c

The pointer is the variables that are used to store/hold the address of another variable, in one sense, any variable in c is just a convenient label for a chunk of the computer’s memory that contains the variable’s data.

A pointer in c is a special kind of variable that contains the location or address of that chunk of memory. (Pointers are so-called because they point to a chunk of memory.)

The address contained by a pointer is a lengthy number that enables you to pinpoint exactly where in the computer’s memory the variable resides.

A pointer is one of the more versatile features of C. There are many good reasons to use them. Knowing a variable’s address in memory enables you to pass the variable to a function by reference.

Also, since functions are just chunks of code in the computer’s memory, and each of them has its own address, you can create pointers to functions too, and knowing a function’s address in memory enables you to pass functions as parameters too, giving your functions the ability to switch among calling numerous functions.

Pointer Declaration: For the declaration of the pointer in c at first we write date type followed by an asterisk ( * ) then we write;

Pointer name: Data Type * Pointer_Name;

For example, suppose we have to declare a pointer to hold the address of integer variable we will declare it as follows:

Int * P; //this is called declaration

The above instruction will declare a pointer P that can hold an address of an integral variable.

Accessing memory of variable using Pointer: For accessing memory using a pointer in c at first we need to assign memory address to the pointer, then we can access, update or insert contents to that memory area. To do this at first we reference it then dereference it.

Referencing Operation: Providing reference we write pointer in c name followed by assignment operator then we write or provide an address;

Pointer_Name = Address of memory(or location);

For example, we have an integer i and its value is 10, we have to access it using a pointer for that we need to declare a pointer and assign the address of i to it. We do it using the following:

Int p;

P = &i;        // This is called referencing.

Now to access the contents of memory we need to dereference it.

Dereferencing a Pointer: In c pointer is dereferenced using asterisk or dereference operator ( * ) followed by pointer name;

*P         // this is called dereferencing.

To create a pointer to a variable, we use the * and & operators. For example, the following code declares a variable called total_cost and a pointer to it called total_cost_ptr;

float total_cost; 
float *total_cost_ptr;
total_cost_ptr = &total_cost;

The `*’ symbol in the declaration of total_cost_ptr is the way to declare that variable to be a pointer in C. You can pronounce the above statement float *total_cost_ptr as declaring float.

Pointer called total_cost_ptr, and you can pronounce the statement total_cost_ptr = &total_cost; as total_cost_ptr take as its value the address of the variable total_cost.

Pointer notation in c:

Consider the declaration,

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 i’s location in memory by the following memory map.

pointer structure in c

We see that 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.

We can print this address number through the following program:

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

The output of the above program would be:

  • Address of i = 65524,
  • Value of i = 3

Look at the first printf( ) statement carefully. ‘&’ used in this statement is C’s ‘address of’ operator. The expression &i returns the address of the variable i, which in this case happens to be 65524. Since 65524 represents an address, there is no question of a sign being associated with it. Hence it is printed out using %u, which is a format specifier for printing an unsigned integer. We have been using the ‘&’ operator all the time in the scanf() statement.

The other pointer operator available in C is ‘*’, called ‘value at address’ operator. It gives the value stored at a particular address. The ‘value at address’ operator is also called ‘indirection’ operator.

Consider the following memory map. As you can see, i value is 3, and j value is i address.

i and j pointer in a c

j is a variable that contains the address of i, it is declared as int *j ;

This declaration tells the compiler that j will be used to store the address of an integer value. In other words, j points to an integer. How do we justify the usage of * in the declaration int *j ;

Let us go by the meaning of *. It stands for ‘value at address’. Thus, int *j would mean, the value at the address contained in j is an int.

Here is a program that demonstrates the relationships we have been discussing.

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

The output of the above program would be:

  • Address of i = 65524
  • Address of i = 65524
  • Address of j = 65522
  • Value of j = 65524
  • Value of i = 3
  • Value of i = 3
  • Value of i = 3

Arithmetic operations on Pointers: Arithmetic operations can be applied to pointers in restricted form because the outcome of the operation is governed by pointer arithmetic.

Pointer uses the following rules of arithmetic:

Addition Operation: If numeric 1 is added to a pointer, then it is incremented by 1 multiplied by the size of a data type. If numeric 2 is added it is increment by 2 multiplied by the size of data type and so on.

For example, suppose we have an integral pointer named P having an address 1002 if numeric 1 is added to it, it will be incremented by 1 multiplied by 2. Because the size of the data type is 2.

int * P ;
P= &i;  //Let the address of i is 1002

(P + 1) it will give result equal to (P + 1 * size of integer) i.e. (P + 1 * 2) that will be (1002 +2) equal to (1004) and (P + 2) it will give result equal to (P + 2 * size of integer) i.e. (P + 2 * 2) that will be  (1002 + 4) equal to (1006).

Increment operation: Generally we use increment operation for arrays. If any pointer is incremented by numeric 1 then it points the address of the next location. You can understand it by assigning the base address of an array to a pointer.

Subtraction Operation: If any pointer is subtracted by numeric 1 then it is decremented by 1 multiplied by the size of a data type. If the pointer is subtracted by numeric 2 then it is decremented by 2 multiplied by the size of a data type.

For example, suppose we have a float pointer named P having an address 1010 if numeric 1 is subtracted from it, it will be decremented by 1 multiplied by 4. Because the size of the data type is 4.

float * P ;
P= &i; //Let the address of i is 1010

(P – 1) it will give result equal to (P – 1 * size of a float) i.e. (P – 1 * 4) that will be (1010 – 4) equal to (1006) and (P – 2) it will give result equal to (P – 2 * size of a float) i.e. (P + 2 * 4) that will be (1010 -8) equal to (1002).

Decrement Operation: Generally we use decrement operation for arrays. If any pointer is decremented by numeric 1 then it points the address of the previous location. You can understand it by assigning the base address of an array to a pointer.

An array of Pointers: An array of pointers is the collection of addresses. For example, suppose we have a declare a pointer that can hold the addresses of 3 variables at a time. To achieve this we need to write the following:

int * P[3]; //This statement will create a pointer that can hold the address of 3 //integral variables.

Let assume we have three variables

int a=10, b=20,c=30;

Then we can assign the address of a,b,c to pointer P by the following statement.

P[0] = &a: 
P[1] = &b;  
P[2] = &c;

For accessing the values of a,b and c through pointer P we write code:

*(P[0]) 
*(P[1]) 
*(P[2])

Significance or importance or advantages of Pointers:

A pointer is used in memory management, optimization, function parameters, etc.

  1. Memory management: Allocating and deallocating memory as needed during run time allows you to create large objects, quickly and immediately free the memory when it is no longer required.
  2. Optimization: Pointers provide a performance advantage by allowing you to access computer memory directly. In a computer program, the fastest way to access and modify an object is to directly access the physical memory where that object is stored.
  3. Function Parameters: Functions can return only one value, but they can take multiple parameters. Bypassing in pointers to variables as parameters, a function can be used to set the values of those variables, and the new values will persist after the function returns. Being able to set the value of several variables at once with a single function call is clean and efficient.

Other uses of pointers are the following:

  • Pointers allow you to implement sharing without copying i.e. pass by reference v/s pass by copying. This allows a tremendous advantage when you are passing around big arrays as arguments to functions. Here you will not have to call the function again and again.
  • Pointers allow us to use dynamic memory allocation.
  • Pointers obviously gives us the ability to implement complex data structures like linked lists, trees, etc
  • Pointers allow us to resize the data structure whenever needed. For example, if you have an array of size 10, it cannot be resized. But, an array created out of malloc and assigned to a pointer can be resized easily by creating a new memory area through malloc and copying the old contents over.

Comment your views about this article and ask any questions related to the pointer.