POINTERS
POINTERS
INTRODUCTION:
Pointers are
another important feature of C language. Although they may appear a little
confusing for beginner, but they are a powerful tool and handy to use once they
are mastered. There are a number of reasons for using pointers.
1. A pointer
enables us to access a variable that is defined outside thefunction.
2. Pointers are
more efficient in handling the data tables.3. Pointers reduce the length and complexity of a program.
4. They increase the execution speed.
5. The use of a pointer array to character strings results in saving of data storage space in memory.
The real power of C lies in the proper use of pointers.
UNDERSTANDING POINTERS:
We know that
computers use their memory for storing the instructions of a program, as well
as the values of a the variables that are associated with it. The computer’s
memory is a sequential collection of ‘storage cells’. Each cell,
commonly known as a byte, has a number called address associated with
it. Typically, the addresses are numbered consecutively, starting from zero.
The last address depends on the memory size. A computer system
having 1KB memory will have its last address as
(1024-1) 1023. Whenever we declare a variable, the system allocates, somewhere in
the memory, an appropriate location to hold the value of the variable. Since, every byte has
a unique address number, this location will have its own address number.
This statement
instructs the system to find a location for the integer variable quantity and
puts the value 179 in that location. Let us assume that the system has chosen
the address location 786 for quantity. Since memory addresses are simply
numbers, they can be assigned to some variables which can be stored in memory,
like any other variable. Such variables that hold memory addresses are called pointers.
A pointer is, nothing but a variable in which address of another variable is
stored.
ACCESSING THE ADDRESS OF A
VARIABLE
The address of
a variable can be known by using the operator &. For example, the
statement
p =
&qty;would assign the address 786 to the variable p. The & operator can be remembered as ‘address of’.
The pointer operator availble in C is ‘ * ’, called ‘value at address’. It gives the value stored at a particular address. The ‘value at address’ operator is also called ‘indirection’ operator.
DECLARING AND INITIALIZING POINTERS
The declaration
of a pointer variable takes the following form:
data type
*pt_name;This tells the compiler three things about the variable pt_name.
1. The asteris (*) tells that the variable pt_name is a pointer variable.
2. pt_name needs a memory location.
3. pt_name points to a variable of type data type.
Example:
int *p;declares the variable p as a pointer variable that points to an integer data type. Remember that the type int refers the data type of the variable being pointed to by p and not the type of the value of the pointer.
Once a pointer
variable has been declared, it can be made to point to a variable using an
assignment statement such as
p = &qty;which causes p to point to qty. That is, p now contains the address of qty. This is known as pointer initialization. Before a pointer is initialized, it should not be used.
corresponding
type of data.
Assigning an absolute address to a pointer variable is prohibited. For example
p = 5368;
A pointer variable can be initialized in its declaration itself. For
example,
int x, *p = &x;
is perfectly valid.
It declares x as an integer variable and p as a pointer variable and then initializes p to the address of x. Note carefully that this is an initialization of p, not *p.
ACCESSING A VARIABLE THROUGH
ITS POINTER
Once a pointer
has been assigned the address of a variable, you can access the value of the
variable using the pointer.
int qty, *p, n;
qty = 179;p = &qty;
n = *p
The first line
declares qty and n as integer variables and p as a pointer
variable pointing to an integer. The second line assign the value 179 to qty
and the third line assigns the address of qty to the pointer variable p.
The fourth line
contains the indirection operator *. When the operator * is placed before a
pointer variable in an expression, the pointer returns the value of the variable
of which the pointer value is the address. In this case, *p returns the value of the variable qty, because p is the
address of qty. The * can be remembered as ‘value at address’. Thus the
value of n would be 179.
The two
statements
p = &qty;n = *p;
are equivalent to
n = *&qty;
which is turn is equivalent to
n = qty;
POINTER EXPRESSIONS
Like other
variables, pointer variables can be used in expressions. For example, if p1 and
p2 are properly declared and initialized pointers, then the following
statements are valid.
y = (*p1) + (*p2);
sum
= sum + (*p1);
The pointer can
be incremented like p1 = p1 + 1; and so on. Remember, however, an expression
like p1++;
will cause the
pointer p1 to point to the next value of its type. For example, if p1 is an
integer pointer with an initial value, say 2800, then after the operation p1 =
p1 + 1, the value of p1 will be 2802, and not 2801. That is, when we
increment a
pointer, its value is increased by the length of the data type that it points
to. This length is called the scale factor.For an IBM PC, the length of various data (scale factor) types are as
follows:
characters 1 byte
integer 2 bytesfloats 4 bytes
long integers 4 bytes
doubles 8 bytes
We can find the
number of bytes needed for a variable by making use of the sizeof operator. For
example, if x is a variable, the sizeof(x) returns the number of bytes needed
for the variable.
POINTERS AND ARRAYS
When an array
is declared, the complier allocates a base address and sufficient amount of storage to contain all
the elements of the array in contiguous memory locations. The base address is
the location of the first element (index
0) 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:
static int x[5]
= {25, 43, 38, 92, 62};
Suppose the
base address of x is 1000 and assuming that each integer requires two bytes,
the five elements will be stored as follows:
Elements x[0] x[1] x[2] x[3] x[4]
Value 25 43
38 92 62Address 1000 1002 1004 1006 1008
The name x is
defined as a constant pointer pointing to the first element, x[0] and therefore
the value of x is 1000, the location where x[0] is stored. That is,
x = &x[0] =
1000
If we declare p
as an integer pointer, then we can make the pointer 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)
POINTERS AND CHARACTER STRINGS
One important
use of pointers is in handling of a table of strings.
Consider the
following array of strings:char name[3][25];
This says that the name is a table containing three names, each with a maximum length of 25 characters (including null character). The total storage requirements for the name table are 75 bytes.
We know that rarely the individual strings will be of equal lengths. 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,
static char
*name[3] = {
“NewZealand”,“Australia”,
“India”
};
declares name
to be an array of three pointers to characters, each pointer pointing to a
particular name as shown below:
name[0]
-------> New Zeeland
name[1]
-------> Australianame[2] --------> India
The character
arrays with the rows of varying length are called ragged arrays and are
better handled by pointers.
POINTERS AND FUNCTIONS
When we pass
addresses to a funtion, the parameters receiving the addresses should be
pointers. The process of calling a function using pointers to pass the
addresses of variable is known as call by reference.
The function
which is called by ‘reference’ can change the value of the variable used in the call. Consider the
following code:
main()
{int x;
x = 20;
change(&x);
printf(“%d\n”, x);
}c
hange(p)
int *p;
{
p* = *p + 10;
}
When the
function change() is called, the address of the variable x, not its value, is
passed into the function change(). Inside change(), the variable p is declared
as a pointer and therefore p is the address of the variable x.
The statement
*p = *p +10;
means ‘add 10
to the value stored at the address p’. Since p represents the address of x, the
value of x is changed from 20 to 30. Therefore, the output of the program will
be 30, not 20.
POINTERS AND STRUCTURES
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 product
is an array variable of struct type. The name product represents
the address of its zeroth element. Consider the following
declaration:
struct
inventory
{char name[30];
int number;
float prince;
} product[2], *ptr;
The assignment
ptr = product;
would assign
the address of the zeroth element of product to ptr. That is, the pointer ptr
will now point to product[0]. Its members can be accessed using the following notation.
ptr -> name
ptr ->
numberptr -> price
The symbol ->
is called the arrow operator and is made up of a minus sign and a
greater than sign. Note that ptr -> is simply another way of writing product[0].
When the
pointer ptr is incremented by one, it is made to point to the next record,
i.e., product[1]. The following for statement will print the values of members
of all the elements of product array.
for(ptr =
product; ptr < product+2; ptr++)
printf(“%s %d
%f\n”, ptr -> name, ptr -> number, ptr -> price);#include<stdio.h>
#include<conio.h>
void main()
{
struct book
{
char name[10];
float price;
int pages;
};
struct book b1={"basic",130.00,550};
struct book *b2;
clrscr();
b2=&b1;
printf("\n name1 = %s",b1.name);
printf("\n price1 = %f",b1.price);
printf("\n pages1 = %d",b1.pages);
printf("\n name2 = %s",b2->name);
printf("\n price2 = %f",b2->price);
printf("\n pages2 = %d",b2->pages);
getch();
}
Comments
Post a Comment