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);

POINTER INCREMENTS AND SCALE FACTOR

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 bytes
floats                               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             62
Address       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] -------> Australia
name[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;

This statement declares product as an array of two elements, each of the type struct inventory and ptr as a pointer to data objects of the type struct Inventory.

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 -> number
ptr -> 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