C Pointers

In this tutorial, we are going to learn pointers, what is pointer, when to use pointers, usage of pointers, pointer that point to a variable, pointer that points to an array or a structure, pointer in UDF etc.,

Introduction

  • A pointer is a variable that represents the location of a data item, such as a variable or an array element.
  • Pointers have a number of useful applications.
    • pointer can be used to pass information back and forth between a function and a reference point.
    • provides a way to return multiple data items from a function via arguments.
    • closely associated with arrays and therefore provide an alternative way to access individual array elements.

Address of (&) operator

As we have seen in scanf() function, & is used just before the variable name, to read and assign the values to the address of the variable.

What is the use of `%p` in printf() in C?

  • In C we have seen different format specifiers.
  • Here we will see another format specifier called %p.
  • This is used to print the pointer type data.
  • %p prints memory address of a variable in hexadecimal form. Let us see the example to get a better idea.

example

void main()
{
	int age = 18;
	char name = 'r';
	float mark = 34.34;		
	printf ("\n address of age  variable =  %p",&age);
	printf ("\n address of name variable =  %p",&name);
	printf ("\n address of mark variable =  %p",&mark);
}

What is Pointer?

Pointer is variable that points to another variable. Lets assume that we have a variable age in our program, &age points to the address of that variable.

To scan a above age variable, we write like this scanf("%d",&age). Address operator & is use to refer an address in C language.

Benefits of Pointer

  • Pointers are more efficient in handling arrays and data tables.
  • Pointers can be used to return multiple values.
  • Use of Pointer arrays to characters strings is helpful in saving memory.
  • It is use to allocate dynamic memory (runtime).
  • Pointer increases the execution speed of a program.

Lets see how to get an address of a variable

#include <stdio.h>

// www.raviroza.com
// 9-Dec-2020, 7.57 pm

void main()
{
  int age = 5;
  printf("Value of age is : %d\n\n", age);

  // get the address of age variable
  printf("Address of age is : %p", &age);  
  getch();
}

How to declare Pointer?

The syntax of pointers is similar to the variable declaration in C, but we use the ( * ) dereferencing operator in the pointer declaration.

Syntax:

dataType *variableName;

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.

Code snippet

int age = 100;

int *ptr;

ptr = &age;

// to alter/change the value of age by using *ptr;

*ptr = *ptr + 1;

Here, age is an integer variable, and *ptr is pointer variable that is referencing or pointing to the variable age.

Interestingly, it is possible to change the value of age variable by using *ptr as it is done in the last line of code.

Guidelines to declare pointers

  • Pointer variables ares declaring using the asterisk (*).
  • Pointer itself needs a memory location.
  • Memory Variable to refer and the pointer variable should of same type, means that a int pointer can refer only a int memory variable.

How to Use Pointers?

  • Pointer Declaration
    • In pointer declaration, we only declare the pointer but do not initialize it.
    • To declare a pointer, we use the ( * ) dereference operator before its name.
    • The pointer declared here will point to some random memory address as it is not initialized.
    • Such pointers are called wild pointers.
  • Pointer Initialization
    • Pointer initialization is the process where we assign some initial value to the pointer variable.
    • We generally use the ( & ) address of operator to get the memory address of a variable and then store it in the pointer variable.
  • Dereferencing
    • 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.
    • Dereferencing a pointer is the process of accessing the value stored in the memory address specified in the pointer.
    • We use the same ( * ) dereferencing operator that we used in the pointer declaration.
Example:
	int var = 10; 
	int * ptr; 
	ptr = &var;
	// or direct pointer definition
	int *ptr = &var; 

AND & OPERATOR

  • Suppose v is a variable that represents some particular data item.
  • The address location can be determined by the expression &v.
  • where & is a unary operator called the address operator.
  • That evaluates the address of its operand.

Types of Pointers

  • Pointers can be classified into many different types based on the parameter on which we are defining their types.
  • If we consider the type of variable stored in the memory location pointed by the pointer, then the pointers can be classified into the following types:
  • Integer Pointer
    • As the name suggests, these are the pointers that point to the integer values.
    • These pointers are pronounced as Pointer to Integer.
    • Similarly, a pointer can point to any primitive data type. It can point also point to derived data types such as arrays and user-defined data types such as structures.
    • example
void main()
{	int age = 10; // int type variable 	
	int*  ptr;    // declare int type pointer
	// data type of ptr and var must be similar
	
	ptr = &age; // assign address of age to pointer
	printf ("\n value   of age = %d",age);	
	printf ("\n address of age = %p",age);	
	printf ("\n value   of ptr = %p",*ptr);
}
  • Array Pointer
    • Pointers and Array are closely related to each other. Even the array name is the pointer to its first element.
    • They are also known as Pointer to Arrays.
    • Pointer to an array using the given syntax.
    • example
int main()
{
   int arr[5] = {1,2,3,4,5};
   int i, *ptr;
   ptr=&arr[0];   
   //clrscr();
   printf ("\n\n POINTERS/ADDRESS OF ARRAY ELEMENTS \n");   
   for(i = 0; i<5; ++i)
   {
      //printf(" &arr[%d] = %p\n", i, &arr[i]);
      printf(" %d \n", *ptr++);      
   }
   printf("\n Base Address of Array is : %p", arr);

   //getch();
}
  • Structure Pointer
    • The pointer pointing to the structure type is called Structure Pointer or Pointer to Structure.
    • It can be declared in the same way as we declare the other primitive data types.
    • In C, structure pointers are used in data structures such as linked lists, trees, etc.
  • Function Pointer
  • Double Pointer
    • In C language, we can define a pointer that stores the memory address of another pointer.
    • Such pointers are called double-pointers or pointers-to-pointer.
    • Instead of pointing to a data value, they point to another pointer.
    • Syntax:
      •   datatype ** ptr_name;

Pointer as function argument

  • Pointers are often passed to a function as arguments.
  • When an argument is passed by reference, however (i.e. when a pointer is passed to a function) the address of a data item is passed to the function.
  • Pointer as a function argument permits the corresponding data item to be altered globally from the called function.
  • The contents of that address can be accessed freely, either within the function or within the calling routine..
  • When pointers are used as argument to a function the formal arguments that are pointers must each be preceded by an asterisk (*). 

example

void main()
{
	int n = 1, v = 3;
	func (&n, &v) ;
	printf (“\n after calling func : n=%d v=%d“ ,n, v);
}
void func (int *pu, int *pv)
{
	*pu = 0;
	*pv = 0;
	printf(“\n within func pu=%d pv=%d”, *pu,*pv);
}

Example – Pointer of int, float and char data type

# include <stdio.h>
# include <conio.h>

// www.raviroza.com
// 11-Dec-2021, 8.00 am

void main()
{
    printf("\n Pointer Demo \n");

    int i = 10;
    int *iptr;
    
    float f = 10.34;
    float *fptr;
    
    char c = 'r';
    char *cptr;
    
    iptr = &i;
    fptr = &f;
    cptr = &c;
    
    printf ("int   : %d is at %p\n",i,iptr);
    printf ("float : %f is at %p\n",f,fptr);
    printf ("char  : %c is at %p\n",c,cptr);
    
    getch();
}

Pointer and Array

The array is also known group of sequential data in memory. Let’s see with an example to get the address of each array element

Example 1 : Address of Array elements

# include <stdio.h>
# include <conio.h>

// www.raviroza.com
// 11-Dec-2021, 9.00 am

void main() 
{
   int arr[5];
   int i;

   printf ("\n\n POINTERS/ADDRESS OF ARRAY ELEMENTS \n");

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

   printf("Base Address of Array is : %p", arr);

   getch();
}

Example 2 : Pointer to an Array

# include <stdio.h>
# include <conio.h>

// www.raviroza.com
// 11-Dec-2021, 9.00 am

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

     // ptr is assigned the address of the 1st element
     ptr = &arr[0]; 

     printf("*ptr     : %d\n", *ptr);      // 1
     printf("*(ptr+1) : %d\n", *(ptr+1));  // 2
     printf("*(ptr+2) : %d",   *(ptr+2));  // 3
     getch();
}

Example 3 : Array of Pointers

# include <stdio.h>
# include <conio.h>

// www.raviroza.com
// 08-Oct-2022, 12.00 pm

void main() 
{
    
    int x=100, y=200;
    // array of integers
    int arr[5] = {1, 2, 3};
     
    // array of integer pointers
    int *ptr[5];
         
    int i;
     
    // assign address of each array elements to pointers
    ptr[0] = &arr[0];
    ptr[1] = &arr[1];
    ptr[2] = &arr[2];
    // assign integer x and y to pointers
    ptr[3] = &x;
    ptr[4] = &y;

    for(i=0; i<5; i++)
    {
        // modify the value of variable x, y and array elements using array of pointers
        *ptr[i] = *ptr[i] + 2;
        printf ("%d  ",*ptr[i]);
    }
    getch();
}

Pointers and Structure

Example 1 : Pointer to Structure

# include <stdio.h>
# include <conio.h>

// www.raviroza.com
// 7-Oct-2022, 8.25 am

struct student
{
   int age;
   float weight;
};

void main()
{
    struct student *studentPtr, student1;
    studentPtr = &student1;   
    clrscr();

    printf("Enter age : ");
    scanf("%d", &studentPtr->age);

    printf("Enter weight : ");
    scanf("%f", &studentPtr->weight);

    printf("Displaying Student Details:\n");
    printf("Age: %d\n", studentPtr->age);
    printf("weight: %f", studentPtr->weight);

    getch();
}

Example 2 : Dynamic memory allocation of structs

# include <stdio.h>
# include <conio.h>

// www.raviroza.com
// 7-Oct-2022, 8.25 am

#include <stdio.h>
#include <stdlib.h>

struct student 
{
   int age;
   char name[30];
};

void main()
{
   struct student *ptr;
   int i, n;

   printf("Enter the number of students: ");
   scanf("%d", &n);

   // allocating memory for N numbers of struct student
   ptr = (struct student*) malloc(n * sizeof(struct student));

   for(i = 0; i < n; ++i)
   {
       printf("Enter first name and age respectively: ");

       // To access members of 1st struct student,
       // ptr->name and ptr->age is used

       // To access members of 2nd struct student,
       // (ptr+1)->name and (ptr+1)->age is used
       scanf("%s %d", (ptr+i)->name, &(ptr+i)->age);
   }

   printf("Displaying Student Information:\n");
   for(i = 0; i < n; ++i)

   {
       printf("Name: %s\tAge: %d\n", (ptr+i)->name, (ptr+i)->age);

   }
   getch();
}

Pointer and Function

When a pointer is passed as an argument to a function, it is also known as function with reference parameter. When a function called by reference is, the address (pointer or address) of a variable is passed to the function. Following is an example of pointer as an argument to a function

# include <stdio.h>
# include <conio.h>

// www.raviroza.com
// 8-Dec-2021, 10.30 am

void byref(int*);

void byref(int *i)
{
	*i = *i + 1;
}

void main()
{
	int temp=10;
	
	byref(&temp);
	printf ("\n\ntemp = %d",temp);
	getch();
}