ALL SIR NOTES HAVE BEEN UPLOADED HERE.
A pointer is a variable which stores the address of another variable. A pointer is a derived data type in C. It is built from one of the fundamental data types available in C. Pointers contain memory addresses as their values. The purpose of pointer is to save memory space and achieve faster execution time.
Pointers are used frequently in C, as they offer a number of benefits to the programmers.
They include:
Pointers can be used to return multiple values from a function via function arguments.
Pointers permit references to functions and thereby facilitating passing of functions as arguments to other functions.
The use of pointer arrays to character strings results in saving of data storage space in memory.
Pointers allow C to support dynamic memory management.
Pointers provide an efficient tool for manipulating dynamic data structures such as structures, linked lists, queues, stacks and trees.
Since pointer variables contain addresses that belong to a separate data type, they must be declared as pointer before we use them. The declaration of a pointer variable takes the following form:
Data_type * p_name;
This tells the compiler three things about the variable p_name.
The asterisk (*) tells that the variable p_name is a pointer variable.
p_name needs a memory location.
. p_name points to a variable of type Data_type.
For example: int *ptr; //pointer to an integer
float *p; // pointer to float
declares the variable ptr as a pointer variable that points to an integer data type and p as a pointer variable that points to a float data type.
The data type of pointer and the variable must match, an int pointer can hold the address of int variable, and similarly a pointer declared with float data type can hold the address of a float variable.
Once a pointer has been assigned the address of a variable, we can access the value of the variable using the operator * (asterisk), usually known as the indirection operator. Another name for the indirection operator is the dereferencing operator.
int num, *ptr, val;
num = 25;
ptr = 25;
val = *ptr;
#include <stdio.h>
void main()
{
int n = 10;
int *ptr;
ptr = &n;
printf(“Address of n = %p”, &n); //using address of operator of variable n
printf(“\nAddress of n = %p”, ptr); //using pointer
printf(“\nValue of n = %d”, *ptr); //using dereference operator
}
There are only a few operations that are allowed to perform on pointers in C language. The operations are slightly different from the ones that we generally use for mathematical calculations. The operations are:
Increment/Decrement of a pointer (++ or --)
Addition of integer to a pointer ( + or +=) Subtraction of integer to a pointer (- or -=)
Subtracting two pointers of the same type
Comparison of two pointers. (p == ptr or p == NULL)
Pointer arithmetic is meaningless unless performed on an array
Void pointer (void *) is a pointer that points to some data location in storage, which doesn’t have any specific type. Void refers to the type. Basically the type of data that is points to is can be any. If we assign address of char data type to void pointer it will become char pointer, if int data type then int pointer and so on. Any pointer type is convertible to a void pointer hence it can point to any value.
Example:
#include <stdio.h>
void main()
{
int inum = 10;
float fnum = 2.2;
void* ptr; //void/generic pointer
ptr = &inum;
// (int*)ptr – does type casting of void
//*((int*)ptr) – dereferences the typecasted void pointer variable
printf("\nValue of inum = %d",*((int*)ptr));
ptr = &fnum; //void pointer is now float
printf("\nValue of fnum = %.2f",*((float*)ptr));
}
Output:
Value of inum = 10
Value of fnum = 2.20
It is possible to make a pointer to point to another pointer. A variable that is a pointer to a
pointer must be declared using additional indirection operator symbols in front the name.
For example:
int *p, **ptr, num;
This declaration tells the compiler that p is a pointer and ptr is a pointer to a pointer of int type.
p = #
ptr = &p;
**p = 15;
When an array is declared, the compiler allocates a base address and sufficient amount of storage to contain all the elements of the array in contiguous memory locations.
Suppose we declare an array num as follows:
int num[50] = { 10, 20, 30, 40, 50 };
if we declare ptr as an integer pointer, then we can make the pointer ptr to point to the array num by the following assignment:
ptr = num; or ptr = &num[0];
now we can access every value of num using ptr++ to move from one element to another.
Pointers can be used to manipulate two-dimensional array as well. For example:
int v[2][3]; is a two-dimensional array,
int *ptr;
if we declare ptr as an int pointer with the initial address of &v[0][0], then
v[i][j] is equivalent to *(ptr+4 * i + j );
C supports a method to create strings using pointer variable of type char. Example
char *name = “Bhagirath”;
This creates a string for the literal and then stores its address in the pointer variable name. Like in one-dimensional arrays, we can use a pointer to access the individual characters in a string
An array of pointers would be a collection of addresses. The addresses present in it can be addresses of isolated variables or addresses of array elements or any other addresses. For example:
int *ptr[3]; //array of integer pointers
int a = 10, b = 20, c = 30;
ptr[0] = &a;
ptr[1] = &b;
ptr[2] = &c;
One important use of pointers is in handling of a table of strings. Consider the following array of strings:
char names[3][20];
This says that the name is a table containing three names, each with a maximum length of 20 characters. We know that rarely the individual strings will be of equal length. Therefore, instead of making each row a fixed number of characters, we can make it a pointer to a string of varying length. For example
char *names[3] = { “Bhagirath”, “Vedant”, “Suraj” };
declares names to be an array of three pointers to characters, each pointer pointing to a particular name.
We know that the name of an array stands for the address of its zeroth element. The same thing is true of the names of arrays of structure variables. Suppose students is an array variable of struct type. The name students represents the address of its zeroth element.
struct record
{
int rollno;
char name[30];
float per;
} students[5], *ptr;
ptr = students;
The pointer ptr will now point to students[0]. Its members can be accessed using the
following notation:
ptr -> rollno;
ptr ->name;
ptr -> per;
The symbol -> is called the arrow operator (also known as member selection operator).
We could also use the notation:
(*ptr).rollno;
Pointers are a little complex to understand.
Pointers can lead to various errors such as segmentation faults or can access a
memorylocation which is not required at all.
If an incorrect value is provided to a pointer, it may cause memory corruption.
Pointers are also responsible for memory leakage.
Pointers are comparatively slower than that of the variables.
Programmers find it very difficult to work with the pointers; therefore it is programmer’sresponsibility to manipulate a pointer carefully.
The process of allocating memory during program execution is called dynamic memory allocation. Dynamic Memory Allocation is manual allocation and freeing of memory according to our programming needs.
C provides some functions to achieve these tasks. There are 4 library functions provided by C defined under <stdlib.h> header file to facilitate dynamic memory allocation in C programming. They are:
malloc()
calloc()
free()
4. realloc()
malloc or ‘memory allocation’ function is used to allocate space in memory during the execution of the program.
malloc function does not initialize the memory allocated during execution. It carries garbage value.
malloc function returns null pointer if it couldn't able to allocate requested amount ofmemory.
Syntax:
ptr = (castType*) malloc (size in bytes);
#include <stdio.h>
#include <stdlib.h>
void main()
{
int size, i. *ptr, sum = 0;
printf(“\nEnter the size of an array: ”);
scanf(“%d”,&size);
ptr = (int*) malloc (size * sizeof(int) );
if(ptr == NULL)
{
printf(“\nNo memory available”);
exit(0);
}
printf(“\nEnter %d elements:”, size);
for(i =0; i < size ; i++)
{
scanf(“%d”, ptr+i);
sum = sum + *(ptr+i);
}
printf(“\nSum = %d”,sum);
free(ptr);
}
“calloc” or “contiguous allocation” method in C is used to dynamically allocate the specified number of blocks of memory of the specified type. it is very much similar to malloc() but has two different points and these are:
It initializes each block with a default value ‘0’.
2. It has two parameters or arguments as compare to malloc().
Syntax:
ptr = (castType*) calloc (n, size in bytes);
realloc function modifies the allocated memory size by malloc and callocfunctions to new size.
If enough space doesn't exist in the memory of the current block to extend, a new block is allocated for the full size of reallocation, then copies the existing data to the new block and then frees the old block.
Dynamically allocated memory created with either calloc() or malloc() doesn't get freed on their own.
free() function frees the allocated memory by malloc(), calloc(), realloc() functions.