Pointers : Pointer is a variable that
contains an address which is a location of another variable in memory.
Declaration of pointer is as follows
Datatype
*ptr-name;
Where
asteristic(*) tells that the variable ‘ptr-name’ is a pointer variable.
Ex : int *p;
Declares
the variable ‘p’ as a pointer variable that points to an integer type elements.
Pointers And Arrays : When an array is declared , the compiler allocates a
base address and sufficient amount of storage of all the elements of array in
categories memory locations. The base address is the location of the first
element of the array. The compiler also defines the array name as a constant
pointer to the first element. Suppose we declare an array ‘X’ as follows.
Int X[5]
= { 1,2,3,4,5};
The name ‘X’ is defined as a
constant pointer pointing to the first element x[0], and the value of ‘X’ is
1000, the location where X[0] store. I.e.., x = &x[0] = 1000.
If
declare ‘P’ as an integer pointer, then we can take the point ‘P’ to point to
the array x by the following assignment P = X;
This is equivalent to P =
& x[0].
We
can access every value of x using P++ to move from one element to another. The
relationship between P and X is shown below.
P = &X[0] = 1000
P+1
= &X[1] = 1002
P
+2 = &X[2] = 1004
P
+3 = &X[3] = 1006
P
+4 = &X[4] = 1008
The address of an element is caliculated using its
index and the scale factor of the data type.
Address
of X[3] = base address + (3*scale factor of int)
=
1000 + (3*2)
=
1006
We
can use the pointer to access the array elements.
i.e..,
*p+3 gives the value of x[3].
Two Dimensional Array : The pointer can be used to
manipulate two dimensional arrays. An element in a two dimensional array can be
represented by the pointer expression as follows
*(*(p+i)
+ j) or
*(* (a+i)+j)
The element of A[i][j] represents the base
address of the array and stationary at this address. The computer allocates
categories space for all the elements in row-wise. i.e.., The first element of
the second row is placed immediately after the last element of the first row
and so on.
Structure Pointers : The
way we can have a pointer pointing to an int
, or a pointer pointing to a character, similarly we can have a pointer
pointing to a struct. Such pointer
are known as ‘structure pointers’, let us look a program which demonistrates
the uses of these pointers .
main()
{
struct book
{
char
name[25];
char author[25];
int callno;
};
struct book1 b1={“My First
Book Of C”,”Shiva”,100};
struct book *ptr ;
ptr=&b1;
printf(“%s%s%d\n”,b1.name,b1.author,b1.callno);
printf(“%s%s%d\n”,ptr->name,ptr->author,ptr->callno);
}
The first printf() is a usual. The second printf() however is perculiar. We can’t use ptr.name or ptr.callno
because ptr is not a structure variable but a pointer to a structure, and the
dot operator requires a structure variable on its left. In such cases C
provides an operator ->, called an arrow operator to refer to the structure
elements. Remember that on the left hand side of the ‘.’ Structure
operator,there must always be a structure variable, whereas on the left hand
side of the -> operator there must
always be a pointer to a structure.
Can we not pass the address of a
structure variable to a function? We can . The following program demonstrates
this.
/*Passing address of a structure
variable*/
struct book
{
char name[25];
char author[25];
int callno;
};
main()
{
struct book b1=”My
Personal Book of C”,”Shiva”,100);
display(&b1);
}
display(b)
struct book *b; {
printf(“\n%s%s%d”,b->name,b->author,b->callno);
}
Again, note that, to access the
structure elements using pointer to a structure we have to use the ‘->’
operator. Also, the structure struct
book should be declared outside main()
such that this data type is available to display() while declaring the variable b as a pointer to the structure.
Dynamic Memory Allocation : Consider
the array declaration
int
marks[100];
Such a declaration would typically be
used if 100 students marks are to be stored in memory. The moment we make this
declaration 200 bytes are reserved in memory for storing 100 integers in it.
However, it may so happen what we actually run the program we might be
interested in storing only 60 students marks. Even in this case 200 bytes would
get reserved in memory, which would result in wastage of memory.
Other way round, there always exists
a possibility that when you run the program you need to store more than 100
student’s marks. In this case the array would fall short in size. Moreover,
there is no way to increase or decrease the array size during execution of the
program. In other words, when we use arrays static memory allocation takes
place. What if we want to allocate memory only at the time of execution? This
is done using standard library functions malloc
() and calloc()
. Since these functions allocate memory – on the fly- during execution they
are often known as ‘Dynamic Memory Allocation functions’. Let us now see a
program which uses the concept of dynamic memory allocation.
#include<alloc.h>
main()
{
int n,avg,I,*p,sum=0;
printf(“Enter the no.of
students”);
scanf(“%d”,&n);
p=(int *)malloc(n *2);
if(p= =NULL)
{
printf(“\nMemory allocation
unsuccessful”);
exit();
}
for(i=0; i<n; i++)
scanf(“%d”,(p+i));
for(i=0; i<n;i++)
sum=sum+*(p+i);
avg=sum/n;
printf(“Average marks
%d”,avg);
}
Here
we first ask for the no.of students whose marks are to be entered and then
allocate as much memory as required to store these marks really. Not a byte
memory, not a byte less. The allocation job is done by malloc() . it returns a NULL
if memory allocation is unsuccessful. If successful it returns the address of
the memory chunk that was allocated .
This
address we collected in an integer pointer p. the expression (int *) is used to type cast the
address being returned as the address of an integer rather than a character.
This type casting is necessary since malloc()
by default returns a pointer to a void. In the first for loop using simple pointer
arthematic we store the marks entered from key board into the memory that has
beeb allocated . In the second for loop we access the same values and sum up
them to find the average marks.
The
calloc() function works exactly similar to malloc() except for the fact that it
needs two arguments as againsdt one argument require by malloc() . for example
int
*p;
p=(int
*) calloc( 10,2);
Here
2 indicates that we wish to indicate memory for storing integers, since an
integer is a 2 byte entity and 10 indicates that we want to reserve space for
storing 10 integers.
Another mirror difference
between malloc() and calloc() is that by default the memory
allocated by malloc() contains
garbage values , where as that allocated by calloc() contains all zeros. While using these functions it is
necessary to include the file “alloc.h” at the beginning of the program.
No comments:
Post a Comment