Professional Documents
Culture Documents
Memory cell
• Consider the declaration, int i =10;
• This declaration tells the compiler to
• reserve space in memory to hold integer value.
• associate the name i with this memory location.
• store the value 10 at this location.
i Location name
10 Value at location
{ 5000 5010
int i=3;
int *j;
j = &i;
printf(“Address of i = %u”,&i);
printf(“Address of i = %u”,j);
printf(“Address of j = %u”,&j);
printf(“value of j = %u”,j);
printf(“value of i = %d”,i);
printf(“value of i = %d”,*j);
printf(“value of i = %d”,*(&i) );
}
Chain of pointers
• It is possible to make a pointer to point to another
pointer.
• A variable that is a pointer to a pointer must be declared
as follows.
• datatype **pointername;
• E.g. int **ptr;
• This declaration tells the compiler that ptr is a pointer to a
pointer of int type.
#include <stdio.h> a p1 p2
int a, *p1,**p2;
a = 100;
p1 = &a;
p2 = &p1;
printf(“value of a = %d”,**p2);
}
Now , a can be accessed by
i. a
ii. *(&a)
iii. *p1
iv. **p2
Pointer Expressions / Arithmetic
• Like other variables , pointer variables can be used in
expressions.
• E.g. int *p1 , *p2;
int a = 5 , b=10 ,c;
p1 = &a;
p2 = &b;
c = *p1 + *p2;
• A pointer can be incremented. When we increment a
pointer , its value is increased by the length of the
datatype that it points to . This length is called the scale
factor.
i.e. everytime a pointer is incremented , it points to the
immediately next location of its type.
Example:
#include <stdio.h>
void main( )
{
int i = 5, *x;
float j = 2.5 , *y;
char k = ‘c’ , *z;
clrscr();
printf(“value of i = %d \n” , i );
printf(“value of j = %f \n” , j);
printf(“value of k = %c \n” , k);
x = &i;
y = &j;
z = &k;
printf(“original address in x = %u \n” , x );
printf(“original address in y = %u \n” , y );
printf(“original address in z = %u \n” , z );
x++;
y++;
z++;
printf(“New address in x = %u \n” , x );
printf(“New address in y = %u \n” , y );
printf(“New address in z = %u \n” , z );
}
Sample output:
value of i = 5
value of j = 2.500000
value of k = c
original address in x = 1000
original address in y = 5000
original address in z = 6000
New address in x = 1002
New address in y = 5004
New address in z = 6001
• The way a pointer can be incremented , it can be
decremented to point to earlier locations.
The following operations can be performed on a pointer.
• Addition of a number to a pointer.
• E.g. int i =4 , *j , *k;
j = &i;
j = j + 9;
k = j + 3;
• Subtraction of a number from a pointer.
• E.g. int i =4 , *j , *k;
j = &i;
j = j - 2;
k = j - 6;
• Comparison of two pointer variables
• Pointer variables can be compared using relational operators provided both
variables point to objects of same data type. Such comparisons can be useful
when both pointer variables point to elements of same array.
#include <stdio.h>
void main( )
{
int arr[ ] = { 10 , 20 , 30 , 40 , 50 , 60};
int *j, *k;
clrscr();
j= &arr[4] ;
k = (arr + 4); /* k = &arr[0] + 4 */
if ( j == k)
printf( “ The two pointers point to the same location”);
else
printf( “ The two pointers do not point to the same location”);
}
• Subtraction of one pointer from another.
• This is possible provided both variables point to elements of the same array .
The resulting value indicates the number of elements separating the
corresponding array elements.
#include <stdio.h>
void main( )
{
int ar[ ] = { 10 , 20 , 30 , 40 , 50 , 60};
int *i , *j;
clrscr();
i = &ar[1] ;
j = &ar[5];
printf(“%d %d “, j – i , *j - *i);
}
Output:
4 40
• Two pointers cannot be added.
• A pointer variable cannot be multiplied with a constant.
• A pointer variable cannot be divided with a constant.
Pointers and Arrays
• When an array is declared , the compiler allocates a base
address and sufficient amount of storage to contain all
the elements of array in contiguous memory locations.
• The base address is the address of first element of array.
The base address can be obtained by &ar[0] or by just
specifying the array name.
int ar[5] = {10 , 20 , 30 , 40 , 50};
10 20 30 40 50
1000 1002 1004 1006 1008
#include <stdio.h>
void main( )
{
int ar[ ] = { 10 , 11 , 12 , 13 , 14};
int i;
clrscr();
for ( i=0 ; i < 5 ; i++)
{
printf(“ \n Address = %u” , &ar[i]);
printf(“ \n Element = %d” , ar[i]);
}
}
• The previous program can be done using pointers.
#include <stdio.h>
void main( )
{
int ar[ ] = { 10 , 11 , 12 , 13 , 14};
int i ,*j;
clrscr();
j = &ar[0]; /* j = ar; */
for ( i=0 ; i < 5 ; i++)
{
printf(“ \n Address = %u” , j);
printf(“ \n Element = %d” , *j);
j++;
}
}
It is also possible to avoid the loop control variable i as follows.
j = ar;
while ( j <= &ar[4] )
{
printf(“%d” , *j);
j++;
int num[6] = { 11 , 22 , 33 , 44 , 55 , 66};
• Just by mentioning num , we get the base address.
• *num gives the first element of the array i.e. 11.
• *num or *(num+0) refer to 11.
• *(num + 1) gives the second element of the array i.e. 22.
• i.e. num[i] is internally converted to * (num + i ).
• num[i] , *(num + i) , *(i+num) , i[num] refers to the same element.
Pointers and Strings
char str[6] = “Hello”;
• We can store Hello at some location in memory by compiler and assign the
address of the string in a char pointer.
• char *p = “Hello”;
void main( )
{
char str1[ ] = “GOOD”;
char str2[10];
char *s = “Hello”;
char *q;
str2 = str1; /* error.(We can’t assign a string to another string) */
q = s; /* allowed (We can assign a char pointer to another char pointer.) */
printf(“%s” ,q);
puts(s); /* s is a pointer to the string . It is also the name of the
string . Therefore no need to use the indirection operator. */
}
• Once a string has been defined , it cannot be initialized to
another set of characters. But such an operation is
perfectly valid with char pointers.
void main( )
{
char str1[ ] = “Hello”;
char *p = “Hello”;
str1 = “Bye”; /* error */
p = “Bye”; /* works */
}
Write a program using pointers to determine the length of a character
string.
#include <stdio.h>
void main( )
{
char *str , *str1;
int length;
str = “ODISHA”;
str1 = str;
while(*str1 != ‘\0’)
{
printf(“%c is stored at address %u \n”, *str1 ,str1);
str1++;
}
length = str1 – str;
printf(“Length of the string :%d”, length);
}
Array of Pointers
• Array of pointers is a collection of addresses.
void main( )
{
int *arr[4]; /* array of 4 integer pointers */
int i = 3, j =4 , k=5 , l=6 ,m;
arr[0]= &i;
arr[1]= &j ;
arr[2]= &k;
arr[3]= &l;
for (m=0; m <4; m++)
{
printf(“%d “,*(arr[m]) );
}
}
• An array of pointers can even contain the addresses of
other arrays.
• char *name[3] = { “India” , “Australia” , “England”};
• name is declared as an array of three pointers to character
strings.
• Each pointer is pointing to a particular name.
• for(i=0 ; i<3; i++)
printf(“%s\n”, name[i]);
• The character arrays with the rows of varying length are
called ragged arrays and are better handled by pointers.
NULL pointer
• Null pointer is a pointer which is pointing to nothing.
• Incase , if we don’t have any address to be assigned to a
pointer , then we can use NULL.
• Pointer which is initialized with NULL value is called as a
NULL pointer.
#include <stdio.h>
void main( )
{
int *ptr = NULL;
printf(“The value of ptr is :%u”, ptr);
}
Wild pointer
• Uninitialized pointers are known as wild pointers.
void main( )
{
int *ptr;
/* ptr is a wild pointer as it is not initialized yet */
int a = 10;
ptr = &a; /* Now ptr is not a wild pointer */
*ptr = 12;
}
Dangling pointer
• A pointer pointing to a memory location that has been deleted or freed is
called dangling pointer.
• Dangling pointers arise when memory is deallocated without modifying the
value of the pointer . The pointer still points to the memory location of the
deallocated memory.
Deallocation of memory
#include <stdio.h>
#include <stdlib.h>
void main( )
{
int *ptr = (int *) malloc (sizeof(int));
............
............
free(ptr);
/* Now ptr becomes a dangling pointer */
ptr = NULL; /* nomore a dangling pointer */
}
Variable goes out of scope
#include <stdio.h>
#include <stdlib.h>
void main( )
{
char *ptr = NULL;
............
............
{
char ch;
ptr = &ch;
}
.............
............. /* ptr is now a dangling pointer */
}
• Pointer variable ptr is pointing to ch declared in the inner block.
• As character variable ch is nonvisible in outer block , pointer is still pointing to
same invalid memory location in outer block , then pointer becomes dangling.
Generic pointer
• When a pointer variable is declared as a pointer to type
void , it is known as a generic pointer.
• E.g. void *p; /* p becomes a generic pointer */
• A generic pointer can be assigned a pointer value of any
basic datatype.
int *ip;
void *p;
p = ip;
• Generic pointers are useful to point to data of different
types at different times.
void main( )
{
int i;
char c;
void *ptr;
i =5;
c =‘a’;
ptr = &i;
printf(“ptr is pointing to %d” , *(int *)ptr);
ptr = &c;
printf(“ptr is pointing to %c” , *(char *)ptr);
}
• Generic pointers cannot be dereferenced. Since we cannot have a variable
of type void , the pointer will not point to any data and therefore cannot be
dereferenced.
• A generic pointer cannot be directly dereferenced but it can however be
done using typecasting the void pointer.
• Pointer arithmetic is not possible on generic pointers.