Class14 (Pointers)
Class14 (Pointers)
Contents:
• Definition of Pointer
– Declaration and Initialization of pointer Variable
– Accessing value of variable through pointer
• Pointer Arithmetic
• Pointer to pointer
• Pointers and Arrays
– Pointer and 1-D array
– Pointer and 2-D array
– Array of Pointers
– Character pointer
• Pointer and Functions
– Pointer as function argument : Call by Value Vs Call By Address
– Function returning more than one value
– Function returning pointer
• Pointers and Structure
– Pointer to a structure
– Self-referencing structure
• Dynamic Memory Allocation
– void pointer
– Static memory allocation Vs Dynamic Memory Allocation
– calloc(), malloc(), realloc() and free()
POINTER : Declaration
A pointer is a variable, which is capable of storing address of another
variable of its type.
Declaration of pointer:
Syntax: <data_type> *<pointer_name>;
e:g: int *ptr; // ptr is a pointer variable of int type, which can hold
address of an integer variable.
#include<stdio.h>
int main()
{
int num=50;
int *ptr=# // Initialization of pointer variable
printf(“Address of num is %u\n”, ptr);
printf(“Value of num is %d\n”, *ptr); //value at address held by
ptr
return 0;
}
Output: Address of num is 6487572
Value of num is 50
POINTER ARITHMETIC
POINTER ARITHMETIC
The pointer is also allowed perform various operations just like normal
variables ( with few restrictions ).
#include<stdio.h>
Output:
int main() a=10 and b=20
{ a=20 and b=20
int a=10,b=20;
int *p,*q;
p=&a;
q=&b;
printf(“a=%d and b=%d\n”,*p,*q); // will print a=10 and b=20
p=q; // Assigning address held by pointer q to pointer p
printf(“a=%d and b=%d\n”,*p,*q); //will print a=20 and b=20
return 0;
}
POINTER ARITHMETIC
2. Addition of a number to a pointer :
It is possible that, we can add a number to a pointer. Let us
consider the following example:
Output:
#include<stdio.h> 10 and 10
int main() 60 and 60
Address held by pointer q is 6487564
{ New address held by pointer q is 6487580
int a=10, *p,*q;
p=&a;
q=p;
printf(“%d and %d\n”,*p,*q); // It will print 10 and 10
*p = *p + 50; // Adding 50 to the value of “a”
printf(“%d and %d\n”,*p,*q);// It will print 60 and 60
printf(“Address held by pointer q is %u\n”, q);
q=q+4; // new address = old address + 4 * sizeof(int)
printf(“New address held by pointer q is %u\n,q);
return 0;
}
POINTER ARITHMETIC
3. Subtraction of a number from a pointer :
It is possible that, we can add a number to a pointer. Let us
consider the following example:
Output:
#include<stdio.h> Value of a = 50
Value of a =40
int main() Current Address is 6487572
{ New Address is 6487560
int a=50, *p;
p=&a;
printf(“Value of a = %d\n”,*p); // It will print a=10
*p = *p - 10; // Subtracting 10 from the value of “a”
printf(“Value of a =%d\n”,*p); // It will print a=40
printf(“Current Address is %u\n”, p);
p=p-3; // new address = old address - 3 * sizeof(int)
printf(“New address is %u\n,p);
return 0;
}
POINTER ARITHMETIC
4. Subtraction of one pointer from another pointer :
It is possible that, we can subtract one pointer variable from
another provided both point to the same array. Let us consider the
following example:
Output:
#include<stdio.h> Address of arr[1] = 6487540 and arr[5] is 6487556
int main() Difference in address is 4
{ Difference in value is 40
int arr[]={10,25,30,45,50,65,70}, *p,*q;
p=&arr[1];
q=&arr[5];
printf("Address of arr[1] = %u and arr[5] is %u\n",p,q);
printf("Difference in address is %u\n",q-p);
printf("Difference in value is %d\n",*q-*p);
return 0;
}
Note: The expression q – p would print 4 but not 16. This is because, q and p
are pointing to locations that are 4 integers apart.
POINTER ARITHMETIC
5. Comparison of two pointer variables:
It is possible that, we can compare pointer variables which points
to same type of elements.
Let us consider the following example:
#include<stdio.h>
int main()
{ Output:
int num=50, *p,*q; Pointing to same location
p=#
q=#
if(p==q)
printf(“Pointing to same location\n”);
else
printf(“Pointing to different location”);
return 0;
}
POINTER ARITHMETIC
6. Incrementing and Decrementing Pointers:
When a pointer to an integer is incremented by one, the address
is incremented by 4 ( as 4 bytes are used for int).
Let us consider the following example:
#include<stdio.h>
int main()
{ Output:
int num=5; Original Address is 6487572
int *ptr; New address is 6487576
ptr=#
printf("Original Address is %u\n",ptr);
ptr++;
printf("New address is %u\n",ptr);
return 0;
}
POINTER TO POINTER
( Multiple Indirection )
POINTER TO POINTER ( Multiple Indirection )
As we know pointer itself is a variable, address of a pointer variable can be
also be stored using another pointer declared by using two indirection
operators.
#include<stdio.h> Output:
int main()
Value of num is 50
{ Value of num is 50
int num=50; Value of num is 50
Address of num is 6487580
int *p=#
Address of num is 6487580
int **q=&p; Address of pointer p is 6487568
printf("Value of num is %d\n",num); Address of num is 6487580
printf("Value of num is %d\n",*p); Address of num is 6487580
1) Pointer to an Array :
The following syntax is used to assign address of an array to a pointer:
We know that, arr will be holding base address i.e &arr[0] => 1000
(arr + 0) => 1000 => Address of 0th element => & arr[0]
(arr + 1) => 1004 => Address of 1st element => & arr[1]
(arr + 2) => 1008 => Address of 2nd element => & arr[2]
(arr + 3) => 1012 => Address of 3rd element => & arr[3]
(arr + 4) => 1016 => Address of 4th element => & arr[4]
Hence, (arr + i ) = (i + arr) = &arr[i] = &i[arr]
POINTER & 1 – D ARRAY
Accessing values of array elements using array as Pointer :
Let us consider the following example :
int arr[]={10,20,30,40,50};
We know that, arr will be holding base address i.e &arr[0] => 1000, hence *arr will
be representing value at address held by arr. i.e arr[0] => 10 ( in this example)
Output:
Address of 0 element is 6487552 and value at index 0 is 10
Address of 1 element is 6487556 and value at index 1 is 20
Address of 2 element is 6487560 and value at index 2 is 30
Address of 3 element is 6487564 and value at index 3 is 40
Address of 4 element is 6487568 and value at index 4 is 50
POINTER & 2 – D ARRAY
1) Pointer to 2-D Array :
The following syntax is used to assign address of a 2-D array to a pointer:
#include<stdio.h>
int main()
{
int a[3][2]={10,20,30,40,50,60};
int *ptr,i;
ptr=a; // Initializing the pointer ptr with base address
for(i=0;i<6;i++)
{
printf("Address = %u and value at address = %d\n",ptr+i,*(ptr+i));
}
return 0;
}
Output:
Address = 6487536 and value at address = 10
Address = 6487540 and value at address = 20
Address = 6487544 and value at address = 30
Address = 6487548 and value at address = 40
Address = 6487552 and value at address = 50
Address = 6487556 and value at address = 60
POINTER & 2 – D ARRAY
2) Array as Pointer : Accessing address and value of each element in 2-D array
Let us consider the following example :
Hence, we can have THREE base addresses i.e. 1000 ( Address of 1st element of
Row 0), 1008 ( Address of 1st element of Row 1) ,1016 ( Address of 1st element of
Row 2)
POINTER & 2 – D ARRAY
//To print base addresses :
#include<stdio.h>
int main()
{
int arr[3][2]={10,20,30,40,50,60};
int i;
for(i=0;i<3;i++)
{
printf("Base Address of row %d = %u\n",i,(arr+i));
//printf("Base Address of row %d = %u\n",i,arr[i]);
}
return 0;
}
Output:
Base Address of row 0 = 6487552
Base Address of row 1 = 6487560
Base Address of row 2 = 6487568
POINTER & 2 – D ARRAY
Now, we have been able to reach each individual row. Suppose we want to refer to
the element arr[2][1] using pointers.
We know (from the above example) that arr[2] would give the address 1016, the
address of second one-dimensional array.
Obviously, (1016+1) would give the address 1020 – i.e. Address of ( arr[2][1] )
*(*(arr+i)+j) Value stored at arr[i][j] i.e. ith row and jth column
POINTER & 2 – D ARRAY
#include<stdio.h> Output:
int main() Array Elements are :
arr[0][0]=10 10 10
{
arr[0][1]=20 20 20
int arr[3][2]={10,20,30,40,50,60}; arr[1][0]=30 30 30
int i,j; arr[1][1]=40 40 40
arr[2][0]=50 50 50
printf("Array Elements are : \n");
arr[2][1]=60 60 60
for(i=0;i<3;i++)
{
for(j=0;j<2;j++)
{
printf("[%d][%d]=%d %d %d \n",i,j,arr[i][j],*(arr[i]+j),*(*(arr+i)+j));
}
}
return 0;
}
ARRAY OF POINTERS
Like we can create an array of integer, floats , we can also create an array
of pointers of particular type.
Declaration:
<data_type> *<pointer_array_name>[<size>];
e:g: int *ptr[5]; // ptr is an array of pointers which can hold addresses
of 5 integer variables.
int a=10,b=50,c=40,d=90,e=20;
ptr[0]=&a; ptr[1]=&b; ptr[2]=&c; ptr[3]=&d; prtr[4]=&e;
ARRAY OF POINTERS
Example:
#include<stdio.h>
int main()
{
int a=10,b=50,c=40,d=90,e=20;
int *ptr[5],i;
ptr[0]=&a; ptr[1]=&b; ptr[2]=&c; ptr[3]=&d; ptr[4]=&e;
for(i=0;i<5;i++)
{
printf("Address held by ptr[%d]=%u value at address is %d\
n",i,ptr[i],*ptr[i]);
}
return 0;
} Output:
Address held by ptr[0]=6487576 value at address is 10
Address held by ptr[1]=6487572 value at address is 50
Address held by ptr[2]=6487568 value at address is 40
Address held by ptr[3]=6487564 value at address is 90
Address held by ptr[4]=6487560 value at address is 20
CHARACTER POINTER
CHARACTER POINTER
When we need to store a string of unknown length, it is difficult to
mention the size of the array.
A character pointer is useful to store a string of unknown length.
//Example
#include <stdio.h>
int main()
{ Output:
char *s = "hello"; String is : hello
printf("String is : %s", s);
return 0;
}
CHARACTER ARRAY Vs CHARACTER POINTER
Example : Character Array Example : Character Pointer
#include<stdio.h> #include<stdio.h>
int main() int main()
{ {
char p[] = "GIET"; char *p = “GIET";
p[2] = ‘F’; // Modifying 3rd Character p[2] = ‘F'; //Modifying 3rd Character
printf("%s", p); printf("%s", p);
return 0; return 0;
} }
For the array, the total string is stored in For the pointer, the pointer variable is
the stack section. Hence, we can edit array stored into stack section, and content is
representation of the string. stored at code section.
Function Declaration:
<return_type> <function_name>(<type1> *,<type2> * );
Ex: void display(int *, double *);
Function Definition:
<return_type> <function_name>(<type1> *<arg1> ,<type2> *<arg2> )
{
// body of the function
}
Ex: void display(int p*, double q*)
{
//body of the function
}
//Example
#include<stdio.h>
void fun(int*); // Function Declaration
int main()
{
int num=100;
printf("Original Value of num = %d\n",num);
fun(&num); // Function call
printf("Updated Value of num = %d\n",num);
}
void fun(int *p) // Function Definition
{
*p = *p + 50; // Modifying value of num through pointer
}
Output:
Original Value of num = 100
Updated Value of num = 150
Call By Value Vs Call By Address
Call by value:
• In call by value method, the value of the actual parameters is copied into the formal
parameters. In other words, we can say that the value of the variable is used in the
function call in the call by value method.
• In call by value method, we can not modify the value of the actual parameter by the
formal parameter.
• In call by value, different memory is allocated for actual and formal parameters since
the value of the actual parameter is copied into the formal parameter.
• The actual parameter is the argument which is used in the function call whereas
formal parameter is the argument which is used in the function definition .
Call by Address:
• In call by address, the address of the variable is passed into the function call as the
actual parameter.
• The value of the actual parameters can be modified by changing the formal
parameters since the address of the actual parameters is passed.
• In call by address, the memory allocation is similar for both formal parameters and
actual parameters. All the operations in the function are performed on the value
stored at the address of the actual parameters, and the modified value gets stored
at the same address.
Swapping values of two variables : An Example
//Call By Value ( Incorrect Version )
#include<stdio.h> Output:
void swap(int,int); Inside Main : Before function Call num1=10 and num2=20
int main() Inside function : p=10 and q=20
Inside function : p=20 and q=10
{ Inside Main : After function Call num1=10 and num2=20
int num1=10,num2=20;
printf("Inside Main : Before function Call num1=%d and num2=%d\n",num1,num2);
swap(num1,num2); // Calling By Value
printf("Inside Main : After function Call num1=%d and num2=%d\n",num1,num2);
return 0;
}
void swap(int p,int q) Note:
{ Changes made by formal arguments will not affect
Actual arguments.
int temp;
printf("Inside function : p=%d and q=%d\n",p,q);
temp=p;
p=q;
q=temp;
printf("Inside function : p=%d and q=%d\n",p,q);
}
Swapping values of two variables : An Example
//Call By Address ( Correct Version )
#include<stdio.h> Output:
void swap(int *,int *); Inside Main : Before function Call num1=10 and num2=20
int main() Inside function : p=10 and q=20
Inside function : p=20 and q=10
{ Inside Main : After function Call num1=20 and num2=10
int num1=10,num2=20;
printf("Inside Main : Before function Call num1=%d and num2=%d\n",num1,num2);
swap( &num1,& num2); // Calling By Address
printf("Inside Main : After function Call num1=%d and num2=%d\n",num1,num2);
return 0;
}
void swap(int *p,int *q) Note:
{ Changes made by formal arguments will affect
Actual arguments.
int temp;
printf("Inside function : p=%d and q=%d\n",*p,*q);
temp=*p;
*p=*q;
*q=temp;
printf("Inside function : p=%d and q=%d\n",*p,*q);
}
Function Returning more than one value
Using call by address, intelligently we can make a function return more than one
value at a time, which is not possible ordinarily. Let us consider the following
example:
#include<stdio.h>
void areaperi(int,float*,float*);
int main()
{
int radius;
float area,perimeter;
printf("Enter radius of a Circle\n");
scanf("%d",&radius);
areaperi(radius,&area,&perimeter);
printf("Area of circle is %f\n",area);
printf("Perimeter of circle is %f\n",perimeter);
return 0;
}
void areaperi(int r,float *a,float *p) Output:
Enter radius of a Circle
{
4
*a=3.14*r*r; Area of circle is 50.240002
*p=2*3.14*r; Perimeter of circle is 25.120001
}
Function Returning Pointer
The way functions return an int, a float, a double or any other data type, it can even
return a pointer. However, to make a function return a pointer it has to be explicitly
mentioned in the calling function as well as in the function definition .
Let us consider the following example:
#include<stdio.h>
int *fun(); // Function Declaration
int main()
Note: (if num is not declared as static)
{
int *ptr; The second printf() will not print 50, because when
ptr=fun(); the control comes back from fun() function, num is
already dead. So even if we have address in ptr, we
printf("Address = %u\n",ptr);
can’t access num since num is already dead.
printf("Value = %d\n",*ptr);
return 0;
}
int *fun()
{
static int num=50; // must be declared as static
return (&num);
} Output:
Address = 4206608
Value = 50
POINTER & STRUCTURES
POINTER TO STRUCTURE
We can declare a pointer to a structure just as for an ordinary data type. To
access the individual members of the structure, we will use structure
pointer operator ( -> )
E:g
struct student
{
int rollno;
char name[20];
}std;
struct student *ptr; // Declaration of structure pointer
ptr=&std; // Initialization of Structure Pointer
POINTER TO STRUCTURE
To access the elements/members of structure through pointer, we can use
either of the following methods:
Ex: (*ptr).rollno
(*ptr).name
#include<stdio.h>
struct student
{
Output:
int rollno;
char name[20]; Enter roll number and name
101
}std; jack
int main() Roll Number = 101
Name = jack
{
struct student *ptr;
printf("Enter roll number and name\n");
scanf("%d%s",&std.rollno,std.name);
ptr=&std; // Initialzing
printf("Roll Number = %d\n",ptr->rollno);
printf("Name = %s",ptr->name);
return 0;
}
SELF REFERENCING STRUCTURE
When a member of a structure is declared as a pointer to the structure itself, then
the structure is called as “self-referencing structure”.
Consider the following declaration:
struct node
{
int data;
struct node *next;
};
Here, struct node consists of two members data and next. The member variable
data is of type int whereas the member next is a pointer to itself (i.e a structure of
type node )
Since, pointer next can point to structure variable of type node, we can connect two
or more such structure variables (say A an B) to obtain linked structure as shown
below:
DYNAMIC MEMORY ALLOCATION
void Pointer
It is a special kind of pointer variable which can hold address of any type of
variable. It is also called “generic pointer”.
A void pointer can point to any kind of variable. While accessing value of
the variable, we need to use typecasting. Let us consider the following
example:
#include<stdio.h> Output:
Address of num = 6487572 and value = 10
int main() Address of ch = 6487571 and value = a
{
int num=10;
char ch='a’;
void *ptr;
ptr=# // Holding address of int type variable
printf("Address of num = %u and value = %d\n",ptr,*(int*)ptr);
ptr=&ch; // Holding address of char type variable
printf("Address of ch = %u and value = %c\n",ptr,*(char*)ptr);
return 0;
}
STATIC Vs DYNAMIC MEMORY ALLOCATION
Static Memory Allocation : The memory which is allocated during
compilation time is known as static memory allocation. Ex: Arrays
For example:
int *ptr;
ptr = (int *) malloc ( 20 ); // Allocates 20 bytes of memory and
which is logically divided into 5 blocks of 4 bytes ( size of int ) each. The
pointer ptr will be holding address of beginning address of the memory
block.
malloc() function : An Example
// Program to find sum of n different numbers using dynamic memory allocation.
#include<stdio.h>
#include<stdlib.h>
int main()
{
int n,i,*ptr,sum=0;
printf("Enter number of elements: ");
scanf("%d",&n);
ptr=(int*)malloc(n*sizeof(int)); //memory allocated using malloc
if(ptr==NULL)
{
printf("Sorry! unable to allocate memory");
exit(0); Output:
}
printf("Enter the elements : \n"); Enter number of elements: 4
Enter the elements
for(i=0;i<n;++i)
10
{ 20
scanf("%d",ptr+i); 40
sum+=*(ptr+i); 60
} 80
printf("Sum=%d",sum); Sum= 210
free(ptr);
return 0;
}
DYNAMIC MEMORY ALLOCATION
calloc() function in C
• The calloc() function allocates the requested memory.
• It initially initialize all bytes to zero.
• It returns NULL if memory is not sufficient.
• It takes two arguments ( Total number of elements and sizeof each
element)
• The syntax of calloc() function is given below:
<Pointer_name >=( <Type> * )calloc(<no of elements>, <size of each element>);
For example:
int *ptr;
ptr = (int *) calloc (5,4 ); // Allocates 20 bytes of memory and
which is logically divided into 5 blocks of 4 bytes ( size of int ) each. The
pointer ptr will be holding address of beginning address of the memory
block.
calloc() function : An Example
// Program to find sum of n different numbers using dynamic memory allocation.
#include<stdio.h>
#include<stdlib.h>
int main()
{
int n,i,*ptr,sum=0;
printf("Enter number of elements: ");
scanf("%d",&n);
ptr=(int*)calloc(n,sizeof(int)); //memory allocated using calloc
if(ptr==NULL)
{
printf("Sorry! unable to allocate memory");
exit(0); Output:
}
printf("Enter the elements : \n"); Enter number of elements: 4
Enter the elements
for(i=0;i<n;++i)
10
{ 20
scanf("%d",ptr+i); 40
sum+=*(ptr+i); 60
} 80
printf("Sum=%d",sum); Sum= 210
free(ptr);
return 0;
}
DYNAMIC MEMORY ALLOCATION: realloc()
realloc() function in C
• If memory is not sufficient by using malloc() or calloc(), we can reallocate
the memory by realloc() function. In short, it changes the memory size.
• Let's see the syntax of realloc() function.
<pointer_name>=realloc(<pointer_name>, new-size) ;
#include <stdio.h>
#include <stdlib.h>
int main()
{
int* ptr;
int n, i;
printf("Enter number of elements:\n");
scanf("%d",&n);
ptr = (int*)calloc(n, sizeof(int));
realloc() function : An Example
if (ptr == NULL) printf("Enter %d elements",n);
{ for(i=0;i<n;i++)
printf("Memory not allocated.\n"); {
exit(0); scanf("%d",ptr+i);
} }
printf("Enter %d elements",n); printf("The elements are: ");
for(i=0;i<n;i++) for (i = 0; i < n; ++i)
{ {
scanf("%d",ptr+i); printf("%d, ", *(ptr+i));
} }
printf("The elements are: "); free(ptr);
for (i = 0; i < n; ++i) return 0;
{ }
printf("%d, ", *(ptr+i));
} Output:
printf(“\nEnter new size \n");
Enter number of elements:
scanf("%d",&n); 3
Enter 3 elements
// Dynamically re-allocate memory using realloc() 11 22 33
ptr = realloc(ptr, n * sizeof(int)); The elements are: 11, 22, 33,
Enter new size
5
Enter 5 elements
11 22 33 44 55
The elements are: 11, 22, 33, 44, 55,
DYNAMIC MEMORY ALLOCATION
free() function in C
• The free() function used to release the memory which is assigned by using
malloc(), calloc() and realloc() function.
• Syntax:
free(<pointer_name>);
Thank you