10. Pointers and Arrays – Object-Oriented Programming with ANSI and Turbo C++

10

CHAPTER

Pointers and Arrays

C
H
A
P
T
E
R

O
U
T
L
I
N
E
—•  10.1 Introduction
—•  10.2 Pointer Declaration
—•  10.3 Void Pointers
—•  10.4 Wild Pointers
—•  10.5 Pointer to Class
—•  10.6 Pointer to Object
—•  10.7 The this Pointer
—•  10.8 Pointer to Derived Classes and Base Classes
—•  10.9 Pointer to Members
—•10.10 Accessing Private Members with Pointers
—•10.11 Direct Access to Private Members
—•10.12 Address of Object and Void Pointers
—•10.13 Arrays
—•10.14 Characteristics of Arrays
—•10.15 Initialization of Arrays Using Functions
—•10.16 Arrays of Classes

10.1 INTRODUCTION

Most of the learners feel that pointer is a puzzling topic. However, pointers can make programs quicker, straightforward and memory efficient. C/C++ gives more importance to pointers. Hence, it is important to know the operation and applications of pointers. Pointers are used as tool in C/C++.

Like C, in C++ variables are used to hold data values during program execution. Every variable when declared occupies certain memory locations. It is possible to access and display the address of memory location of variables using ‘&’ operator. Memory is arranged in series of bytes. These series of bytes are numbered from zero onwards. The number specified to a cell is known as memory address. Pointer variable stores the memory address of any type of variable. The pointer variable and normal variable should be of the same type. The pointer is denoted by (*) asterisk symbol.

A byte is nothing but combination of eight bits as shown in Figure 10.1. The binary numbers 0 and 1 are known as bits. Each byte in the memory is specified with a unique (matchless) memory address. The memory address is an unsigned integer starting from zero to uppermost addressing capacity of the microprocessor. The number of memory locations pointed by a pointer depends on the type of pointer. The programmer should not worry about the addressing procedure of variables .The compiler takes the procedure itself. The pointers are either 16 bits or 32 bits long.

Fig. 10.1 Memory representation

The allocation of memory during program run-time is called as dynamic memory allocation. Such type of memory allocation is essential for data structures and can efficiently handle them using pointers. Another reason to use pointers is in array. Arrays are used to store more values. Actually, the name of array is a pointer. One more reason to use pointers is command-line arguments. Command line arguments are passed to programs and are stored in an array of pointers argv[] . The command line arguments and dynamic memory allocation are illustrated in the forthcoming chapters.

POINTER

A pointer is a memory variable that stores a memory address. Pointers can have any name that is legal for other variables and it is declared in the same fashion like other variables but it is always denoted by ‘*’ operator.

(1) Features of Pointers

(1) Pointers save the memory space.

(2) Execution time with pointer is faster because data is manipulated with the address i.e., direct access to memory location.

(3) The memory is accessed efficiently with the pointers. The pointer assigns the memory space dynamically that leads you to reserve a specific bytes in the memory.

(4) Pointers are used with data structures. They are useful for representing two-dimensional and multi-dimensional arrays.

(5) In C++, a pointer declared to a base class could access the objects of derived class. Whereas a pointer to derived class cannot access the objects of base class. The compiler will generate an error message cannot convert ‘ A* to ‘B *’ where A is the base class and B is the derived class.

10.2 POINTER DECLARATION

Pointer variables can be declared as below:

Example

int *x;

float *f;

char *y;

(1) In the first statement ‘x’ is an integer pointer and it informs to the compiler that it holds the address of any integer variable. In the same way, ‘f’ is a float pointer that stores the address of any float variable and ‘y’ is a character pointer that stores the address of any character variable.

(2) The indirection operator (*) is also called the deference operator. When a pointer is dereferenced, the value at that address stored by the pointer is retrieved.

(3) Normal variable provides direct access to their own values whereas a pointer indirectly accesses the value of a variable to which it points.

(4) The indirection operator (*) is used in two distinct ways with pointers, declaration and deference.

(5) When a pointer is declared, the star indicates that it is a pointer, not a normal variable.

(6) When the pointer is dereferenced, the indirection operator indicates that the value at that memory location stored in the pointer is to be accessed rather than the address itself.

(7) Also note that * is the same operator that can be used as the multiplication operator. The compiler knows which operator to call, based on context.

(8) The ‘&’ is the address operator and it represents the address of the variable. The address of any variable is a whole number. The operator ‘&’ immediately preceding the variable returns the address of the variable. In the example given below ‘&’ is immediately preceding the variable ‘num’ which provides address of the variable.

10.1 Write a program to display the address of the variable.

# include <iostream.h>
# include <conio.h>


main( )
{
  int n;
  clrscr( );
  cout <<"Enter a Number = ";

  cin >>n;
  cout <<"Value of n =  "<<n;
  cout <<"Address of n= " <<(unsigned)&n;
  getch( );
}

OUTPUT :

Enter a Number = 10

Value of n = 10

Address of n=4068

Explanation: The memory location of a variable is system dependent. Hence, address of a variable cannot be predicted immediately. In the above example, the address of the variable ‘n’ observed is 4068. In Figure 10.2 three blocks are shown related to the above program. The first block contains variable name. The second block represents the value of the variable. The third block is the address of the variable ‘n’ where 10 is stored. Here, 4068 is the memory address. The address of variable depends on various things for instance memory model, addressing scheme and present system settings.

Fig. 10.2 Variable and its memory address

10.2 Write a program to declare a pointer. Display the value and address of the variable using pointers.

# include <stdio.h>
# include <iostream.h>
# include <conio.h>


void main( )
{
  int *p;
  int x=10;
  p=&x;
  clrscr( );
  printf ("\n  x=%d  &x=%u  \t(Using printf( ))",x,p);

  cout   <<"\n  x="<<x <<"  &x="  <<&x <<"   (Using cout( ))";
  printf ("\n  x=%d  &x=%u   \t(Using pointer)",*p,p);
  cout   <<"\n *p="<<*p <<"\t&p=" <<p <<"\t(Contents of pointer)";
}

OUTPUT

x = 10 &x = 65524            (Using printf( ))

x = 10 &x = 0x8f94fff4     (Using cout( ))

x = 10 &x = 65524            (Using pointer)

*p = 10 &p = 0x8f94fff4   (Contents of pointer)

Explanation: In the above program, *p is an integer pointer and x is an integer variable. The address of variable x is assigned to pointer p. Ampersand (&) operator preceded with variable displays the memory location of that variable. The printf( ) and cout( ) statements display address in different formats. The printf( ) statement displays the address as an unsigned integer whereas the cout( ) statement displays the address in hexadecimal format. We can access the contents of variable x using pointer p. Output of the program is shown above.

10.3 Write a program to display memory address of a variable. Typecast the memory address from hexadecimal to unsigned integer.

#include<iostream.h>
#include<conio.h>
void main( )
{
 int a;
 float b;
 char c;
 clrscr( );
 cout<<"\n Enter integer number = ";
 cin>>a;
 cout<<"\n Enter float number   = ";
 cin>>b;
 cout<<"\n Enter character      = ";
 cin>>c;
 cout<<"\nThe entered int    is = "<<a;
 cout<<"\nThe entered float  is = "<<b;

 cout<<"\nThe entered char   is = "<<c;
 cout<<"\n\nThe entered number is stored at location = "<<(unsigned)&a;
 cout<<"\nThe entered float  is stored at location= "<<(unsigned)&b;
 cout<<"\nThe entered char   is stored at location = "<<(unsigned)&c;
 getch( );
}

OUTPUT

Enter integer number = 34

Enter float number   = 343.34

Enter character    = g

The entered int is    = 34

The entered float is = 343.339996

The entered char is = g

The entered number is stored at location = 4096

The entered float is stored at location= 4092

The entered char is stored at location = 4091

Explanation: In the above program, variables a, b and c of int, float and char type are declared. The entered values with their addresses are displayed. The addresses of the variables are displayed by preceding ampersand (&) operator with variable name. The typecasting syntax (unsigned) is done to typecast hexadecimal address into unsigned integer.

Here, you can observe the addresses in descending order. This is because all automatic variables are stored in stack. The stack always starts from top to lower memory addresses.

10.3 VOID POINTERS

Pointers can also be declared as void type. Void pointers cannot be dereferenced without explicit type conversion. This is because being void the compiler cannot determine the size of the object that the pointer points to. Though void pointer declaration is possible, void variable declaration is not allowed. Thus, the declaration void p will display an error message “Size of ‘p’ is unknown or zero” after compilation.

It is not possible to declare void variables like pointers. Pointers point to an existing entity. A void pointer can point to any type of variable with proper typecasting. The size of void pointer displayed will be two. When pointer is declared as void, two bytes are allocated to it. Later using typecasting, number of bytes can be allocated or de-allocated. Void variables cannot be declared because memory is not allocated to them and there is no place to store the address. Therefore, void variables cannot actually serve the job they are made for.

10.4 Write a program to declare a void pointer. Assign address of int, float, and char variables to the void pointer using typecasting method. Display the contents of various variables.

                            //  void pointers //
# include <stdio.h>
# include <iostream.h>
# include <conio.h>


int p;
float d;
char c;


      void *pt = &p;        // pt points to p


void main (void)
{
      clrscr( );
      *(int *) pt = 12;
      cout <<"\n p="<<p;
      pt = &d;              // pt points to d
      *(float *)pt = 5.4;
      cout <<"\n r="<<d;
      pt=&c;                  // pt points to c
      *(char* )pt='S';
      cout <<"\n c="<<c;
}

OUTPUT

p=12

r=5.4

c=S

Explanation: In the above example, variables p, d, and c are variables of type int, float, and char respectively. Pointer pt is a pointer of type void. These entire variables are declared before main( ). The pointer is initialized with the address of integer variable p i.e., the pointer p points to variable x.

The statement *(int *) pt = 12 assigns the integer value 12 to pointer pt i.e., to a variable p. The contents of variable p are displayed using the succeeding statements. The declaration *(int *) tells the compiler the value assigned is of integer type. Thus, assignment of float and char type is carried out. The statements *(int *) pt = 12, *(float *) pt = 5.4 and *(char*) pt=’S’ help the compiler to exactly determine the size of data types.

10.4 WILD POINTERS

Pointers are used to store memory addresses. An improper use of pointers creates many errors in the program. Hence, pointers should be handled cautiously. When pointer points to an unallocated memory location or to data value whose memory is deallocated, such a pointer is called as wild pointer. The wild pointer generates garbage memory location and pendent reference.

When a pointer pointing to a memory location gets vanished, the memory turns into garbage memory. It indicates that memory location exists but pointer is destroyed. This happens when memory is not de-allocated explicitly.

The pointer becomes wild pointer due to the following reasons:

     (1) Pointer declared but not initialized

     (2) Pointer alteration

     (3) Accessing destroyed data

(1) When a pointer is declared and not initialized, it holds an illicit address. It is very hard to manipulate such a pointer. Consider the following example:

10.5 Write a program to use wild pointer.

# include <iostream.h>
# include <conio.h>



int main( )
{
  clrscr( );
  int *x;
  for (int k=0;k<10;k++)
  cout <<x[k]<<" ";
  return 0;
}

OUTPUT

28005 27760 29793 29541 29728 8303 25954 28704 25205 26988

Explanation: In the above program, pointer x is declared and not initialized. Using for loop the location containing pointer is increased and successive addresses are displayed.

(2) The careless assignment of new memory location in a pointer is called as pointer alteration. This happens when other wild pointer accesses the location of a legal pointer. The wild pointer converts a legal pointer to wild pointer.

(3) Sometimes the pointers attempt to access data that has no longer life. The program given next illustrates this:

10.6 Write a program to show display output when a pointer accesses a temporary data of the memory.

# include <iostream.h>
# include <conio.h>


char *instring( );
char *inchar( );


void main( )
{
      clrscr( );
      char *ps,*pc;
      ps=instring( );
      pc=inchar( );
      cout <<" String    : "<<*ps<<endl;
      cout <<" Character : "<<*pc<<endl;
}


      char *instring( )
      {
        char str[]= "cpp ";
        return str;          }



      char *inchar( )
      {
        char g;
        g='D';
        return &g;  }

OUTPUT

String : c

Character :

Explanation: In the above program, ps and pc are character pointers. The function instring( ) and inchar( ) returns reference (base address of the string or character) and they are stored in the pointer ps and pc respectively. In both the functions the character variables str and g are local. When the control exists from these function and returns to main( ), local variables inside the user-defined functions are destroyed. Thus, the pointers ps and pc point to the data that is destroyed. The contents displayed by the pointers are shown in the output.

10.5 POINTER TO CLASS

We know that pointer is a variable that holds the address of another data variable. The variable may be of any data type i.e., int, float or double. In the same way, we can also define pointer to class. Here, starting address of the member variables can be accessed. Such pointers are called class pointers.

Example:

class book
{char name [25];
  char author [25];
  int pages;
};


a) class book *ptr;
   or
a) struct book *ptr;

In the above example, *ptr is pointer to class book. Both the statements (a) and (b) are valid. The syntax for using pointer with member is given below.

1) ptr->name 2) ptr->author 3) ptr->pages.

By executing these three statements, starting address of each member can be estimated.

10.7 Write a program to declare a class. Declare pointer to class. Initialize and display the contents of the class member.

# include <iostream.h>
# include <conio.h>
void main( )
{


  class man
  {
       public :
       char name[10];
       int  age;
  };


man m={"RAVINDRA", 15};
man *ptr;


ptr=&(man)m;

// *ptr=(man)m;
// *ptr=man(m);
// *ptr=m;
//ptr=&m;


clrscr( );
cout <<"\n" <<m.name <<" "<<m.age;
cout <<"\n"<<ptr->name<<" "<<ptr->age;


}

OUTPUT

RAVINDRA 15

RAVINDRA 15

Explanation: In the above program, the pointer ptr points to the object m. The statement ptr=&(man) m; assigns address of first member element of the class to the pointer ptr. Using the dot operator and arrow operator, contents can be displayed. The display of class contents is possible because the class variables are declared as public. The statements given below can also be used to assign address of objects to the pointer.

ptr=&(man)m;

*ptr=(man)m;

*ptr=man(m);

*ptr=m;

ptr=&m;

10.6 POINTER TO OBJECT

Like variables, objects also have an address. A pointer can point to specified object. The following program illustrates this.

10.8 Write a program to declare an object and pointer to the class. Invoke member functions using pointer.

# include <iostream.h>
# include <conio.h>


class Bill
{
      int   qty;
      float price;

      float amount;


      public :


      void getdata (int a, float b, float c)
      {
        qty=a;
        price=b;
        amount=c;
      }


      void show( )
      {
        cout <<"Quantity   : " <<qty <<"\n";
        cout <<"Price      : " <<price <<"\n";
        cout <<"Amount     : " <<amount <<"\n";
      }
};


int main( )
{
      clrscr( );
      Bill s;
      Bill *ptr =&s;
      ptr->getdata(45,10.25,45*10.25);
      (*ptr).show( );
      return 0;
}

OUTPUT

Quantity   : 45

Price         : 10.25

Amount    : 461.25

Explanation: In the above program, the class Bill contains two float and one integer member. The class Bill also contains member functions getdata( ) and show( ) to read and display the data. In function main( ), s is an object of class Bill and ptr is pointer to the same class. The address of object s is assigned to pointer ptr. Using pointer ptr with arrow operator (->) and dot operator(.), member functions are invoked. The statements used for invoking functions are given next.

ptr->getdata (45,10.25,45*10.25);

(*ptr).show ( );

Here, both the pointer declarations are valid. In the second statement, ptr is enclosed in the bracket because the dot operator (.) has higher precedence as compared to the indirection operator (*).

10.9 Write a program to create dynamically an array of objects of class type. Use new operator.

# include <iostream.h>
# include <conio.h>


class Bill
{
      int   qty;
      float price;
      float amount;


      public :


      void getdata (int a, float b, float c)
      {
            qty=a;
            price=b;
            amount=c;
      }


      void show( )
      {
        cout <<"Quantity   : " <<qty <<"\n";
        cout <<"Price     : " <<price <<"\n";
        cout <<"Amount    : " <<amount <<"\n";
      }


};


int main( )
{
      clrscr( );


      Bill *s= new Bill[2];

      Bill *d =s;
      int x,i;
      float y;


      for (i=0;i<2;i++)
      {
        cout <<"\nEnter Quantity and Price : ";
        cin >>x >>y;
        s->getdata(x,y,x*y);
        s++;
      }


      for (i=0;i<2;i++)
      {
        cout <<endl;
        d->show( );
        d++;
      }


      return 0;
}

OUTPUT

Enter Quantity and Price : 5 5.3

Enter Quantity and Price : 8 9.5

Quantity    : 5

Price          : 5.3

Amount     : 26.5

Quantity    : 8

Price          : 9.5

Amount     : 76

Explanation: In the above program, the class Bill is same as in the previous example. In main( ), using new memory allocation operator, memory required for two objects is allocated to pointer s i.e., 10 bytes. The first for loop accepts the data through the keyboard. Immediately after this, the data is sent to the member function getdata( ). The pointer s is incremented. After incrimination, it points to the next memory location of its type. Thus, two records are read through the keyboard. The second for loop is used to display the contents on the screen. Here, the function show( ) is invoked. The logic used is same as in the first loop. The functions are invoked using pointer and it is explained in the previous example.

10.7 THE this POINTER

Use of this pointer is now outdated. The objects are used to invoke the non-static member functions of the class. For example, if p is an object of class P and get( ) is a member function of P, the statement p.get( ) is used to call the function. The statement p.get( ) operates on p. In the same way if ptr is a pointer to P object, the function called ptr->get( ) operates on *ptr.

However, the question is, how does the member function get( ) understand which p it is functioning on? C++ compiler provides get( ) with a pointer to p called this. The pointer this is transferred as an unseen parameter in all calls to non-static member functions. The keyword this is a local variable that is always present in the body of any non-static member function.

The keyword this does not need to be declared. The pointer is rarely referred to explicitly in a function definition. However, it is used implicitly within the function for member references. For example, if p.get(k) is called, where k is a member of P, the keyword this is set to &p and k is set to this->k, which is equivalent to p.k. Figure 10.3 shows working of this pointer.

10.10 Write a program to use this pointer and return pointer reference.

# include <iostream.h>
# include <conio.h>


      class number
      {
        int num;
        public :


      void input( )
      {
        cout <<"\n Enter a Number : ";
        cin >>num;
      }


      void show( )
      {  cout <<"\n The Minimum Number : "<<num; }


      number  min( number t)
      {if (t.num<num)
        return t;
        else
        return *this;       }
	
};


void main( )
{
clrscr( );


number n,n1,n2;
n1.input( );
n2.input( );
n=n1.min(n2);
n.show( );
}

OUTPUT

Enter a Number : 152

Enter a Number : 458

The Minimum Number : 152

Explanation: In the above program, the class number contains one integer number variable num. The class also contains member functions input( ), show( ) and min( ). The input( ) function reads an integer through the keyboard. The show( ) function displays the contents on the screen. The min( ) function finds minimum number out of two. The variables n, n1, and n2 are objects of class number.

In function main( ), the objects n1 and n2 calls the function input( ) and read integer. Both the objects n1 and n2 are passed to function min( ) with the statement n=n1.min(n2) . The object n receives the returned value by the function min( ). The object n1 calls the function min( ). The object n2 is passed as an argument in function min( ).

In function num( ), the formal object t receives the contents of argument n2. In the same function, the object n1 is also accessible. We know that the pointer this is present in the body of every non-static member function. The pointer this points to the object n1. Using pointer this we can access the individual member variables of object n1. The if statement compares the two objects and return statement returns the smaller objects.

10.8 POINTER TO DERIVED CLASSES AND BASE CLASSES

It is possible to declare a pointer which points to the base class as well as the derived class. One pointer can point to different classes. For example, X is a base class and Y is a derived class. The pointer pointing to X can also point to Y.

Fig.10.3 Working of this

10.11 Write a program to declare a pointer to the base class and access the member variable of base and derived class.

                         // Pointer to base object //


# include <iostream.h>
# include <conio.h>


      class A
      {
            public :
            int b;
            void display( )
            {
            cout <<"b = " <<b <<"\n";
      }
      };


class B : public A
{
      public :
      int d;
      void display( )
      {

      cout <<"b= " <<b <<"\n" <<" d="<<d <<"\n";
      }


 };


 main( )
  {
  clrscr( );
 A *cp;
 A base;
  cp=&base;
  cp->b=100;
//  cp->d=200; Not Accessible
 cout <<"\n cp points to the base object \n";
 cp->display( );


 B b;


 cout <<"\n cp points to the derived class \n";
 cp=&b;
  cp->b=150;
// cp->d=300;  Not accessible
  cp->display( );
  return 0;
  }

OUTPUT

cp points to the base object

b = 100

cp points to the derived class

b = 150

Explanation: In the above program, A and B are two classes with one integer member variable and member function. The class B is derived from class A. The pointer cp points to the class A. The variable base is an object of the class A. The address of object base is assigned to pointer cp. The pointer cp can access the member variable b, a member of base class but cannot access variable d, a member of derived class. Thus, the following statement is invalid.

(a) cp->d=200;

The variable b is an object of class B. The address of object b is assigned to the pointer cp. However, b is an object of derived class and access to member variable d is not possible. Thus, the following statement is invalid.

(b) cp->d=300;

Here, cp is pointer to the base class and could not access the members of derived class.

10.12 Write a program to declare a pointer to the derived class and access the member variables of base and derived class.

                 // Pointer to derived object //


# include <iostream.h>
# include <conio.h>


      class A
      {
        public :
        int b;
        void display( )
      {
      cout <<"b = " <<b <<"\n";
      }
      };


class B : public A
{
      public :
      int d;
      void display( )
      {
      cout <<"\tb= " <<b <<"\n" <<"\td= "<<d <<"\n";
      }


};


main( )
{
clrscr( );
B *cp;
B b;

cp=&b;
cp->b=100;
cp->d=350;


cout <<"\n cp points to the derived object \n";
cp->display( );
return 0;
}

OUTPUT

cp points to the derived object

     b= 100

     d= 350

Explanation: The above program is same as the previous one. The only difference is that the pointer cp points to the objects of derived class. The pointer cp is pointer to class B. The variable b is an object of class B. The address of b is assigned to the pointer cp. The pointer cp can access the member variables of both base and derived classes. The output of the program is shown above.

10.13 Write a program to declare object and pointer to class. Assign value of pointer to object. Display their values. Also carry out conversion from basic type to class type.

# include <iostream.h>
# include <conio.h>
# include <alloc.h>
class A
{
  private :
  int a;
  public:


     A ( )   { a=30;  }


     void show ( )  { cout <<"\n a = "<<a ;}


     A (int x)      {   this->a=x;   }
};


int main( )
{

clrscr( );


A k,*b,a;
*b=50;
k=*b;
     b->show( );
     a.show( );
     k.show( );
     return 0;
}

OUTPUT

a = 50

a = 30

a = 50

Explanation: In the above program, a and k are objects of class A. The *b is a pointer object. The objects a and k are initialized to 30 by the constructor. The statement *b=50 assigns 50 to data member a. This is carried out by the conversion constructor A(int). The value of *b is assigned to object k. The member function show( ) is called by all the three objects. The output of the program is given above.

10.9 POINTER TO MEMBERS

It is possible to obtain address of member variables and store it to a pointer. The following programs explain how to obtain address and accessing member variables with pointers.

10.14 Write a program to initialize and display the contents of the structure using dot (.) and arrow (->) operator.

# include <iostream.h>
# include <conio.h>


int main ( )
{
  clrscr( );


  struct c
{
  char *name;
};

c b, *bp;
bp->name=" CPP";
b.name="C &";
cout<<b.name;
cout<<bp->name;
return 0;
}

OUTPUT

C & CPP

Explanation: In the above program, structure c is declared. The variable b is object and bp is a pointer object to structure c. The elements are initialized and displayed using dot (.) and arrow (->) operators. These are the traditional operators which are commonly used in C. C++ allows two new operators .* and ->* to carry the same task. These C++ operators are recognized as pointer to member operators.

10.15 Write a program to initialize and display the contents of the structure using .* and arrow ->* operator.

# include <iostream.h>
# include <conio.h>



struct data
{
     int x;
     float y;
};


int main ( )
{
     clrscr( );
     int   data ::*xp=&data::x;
     float data::*yp=&data::y;


     data d={11,1.14};
     cout <<endl<<d.*xp<<endl<<d.*yp;


     data *pp;


     pp=&d;

     cout<<endl<<pp->*xp<<endl<<pp->*yp;


     d.*xp=22;
     pp->*yp=8.25;
     cout <<endl<<d.*xp<<endl<<d.*yp;
     cout<<endl<<pp->*xp<<endl<<pp->*yp;
     return 0;
}

OUTPUT

11

1.14

11

1.14

22

8.25

22

8.25

Explanation: In the above program, struct data is defined and it has two data members of integer and float type. Consider the following statements:

int data ::*xp=&data::x;

float data::*yp=&data::y;

The *xp and *yp are pointers. The class name followed by scope access operator points that they are pointers to member variables of structures int x and float y. The rest part of the statement initializes the pointers with addresses of x and y respectively.

The rest part of the program uses operators .* and ->* to initialize and access the member elements in the same fashion like the operator dot(.) and arrow(->).

10.16 Write a program to declare and initialize an array. Access and display the elements using .* and ->* operators.

# include <iostream.h>
# include <conio.h>


struct data
{int x;
  float y;
};

int main( )
{clrscr( );
  int   data ::*xp=&data::x;
  float data::*yp=&data::y;


  data darr[]={  {12,2.5},
  {58,2.4},
  {15,5.7} };


  for ( int j=0;j<=2;j++)
  cout <<endl<<darr[j].*xp<<"    "<<darr[j].*yp;
  return 0;
}

OUTPUT

12 2.5

58 2.4

15 5.7

Explanation: The above program is the same as the last one. An array darr[] is initialized. The for loop and the operator .* accesses the elements and elements are displayed on the console.

10.17 Write a program to declare variables and pointers as members of class and access them using pointer to members.

# include <iostream.h>
# include <conio.h>


class data
{
     public:


     int x;
     float y;
     int *z;
     float *k;
     int **l;
     float **m;
};

void main( )
{
  clrscr( );
  int data::*xp=&data::x;
  float data ::*yp=&data::y;


  int *data::*zp=&data::z;
  float *data::*kp=&data::k;


  int **data::*lp=&data::l;
  float **data::*mp=&data::m;


  data ob={51,4.58,&ob.x,&ob.y,&ob.z,&ob.k};
  data *pp;
  pp=&ob;


  cout <<endl<<ob.*xp<<endl<<ob.*yp;
  cout <<endl<<*(ob.*zp)<<endl<<*(ob.*kp);
  cout<<endl<<**(ob.*lp)<<endl<<**(ob.*mp);


  cout <<endl<<pp->*xp<<endl<<pp->*yp;
  cout<<endl<<*(pp->*zp)<<endl<<*(pp->*kp);
  cout <<endl<<**(pp->*lp)<<endl<<**(pp->*mp);


  *(ob.*zp)=11;
  **(pp->*mp)=8.24;


  cout <<endl<<ob.*xp<<endl<<ob.*yp;
}

OUTPUT

51

4.58

51

4.58

51

4.58

51

4.58

51

4.58

51

4.58

11

8.24

Explanation: In the above program, the class and data are declared and all members are public. The ob is an object of the class data and it is initialized. The variable pp is a pointer and initialized with address of object ob. The rest program statements use the pointer to member operators and display the contents of the class on the screen.

TIP

Pointers to members are not associated with any particular object.

10.18 Write a program that invokes member functions using pointer to functions.

# include <iostream.h>
# include <conio.h>


class data
{
  public :


  void joy1( )  {  cout <<endl<<(unsigned)this<<" in joy1";   }


  void joy2( )  {  cout <<endl<<(unsigned)this<<" in joy2";  }


  void joy3( )  {  cout <<endl<<(unsigned)this<<" in joy3" <<endl; }


};


void main( )
{
  clrscr( );
  data od[4];


  void (data ::*m[3])( )={&data::joy1,&data::joy2,&data::joy3};


for (int x=0;x<=3;x++)

{
  for (int y=0;y<=2;y++)   (od[x].*m[y])( );
}


}

OUTPUT

65522 in joy1

65522 in joy2

65522 in joy3

65523 in joy1

65523 in joy2

65523 in joy3

65524 in joy1

65524 in joy2

65524 in joy3

65525 in joy1

65525 in joy2

65525 in joy3

Explanation: In the above program, class data has three-member variables joyl, joy2, and joy3. The array m[3])( ) holds the addresses of member functions. The nested for loops and statement within it invokes member functions.

10.19 Write a program to declare pointer to member variable and display the contents of the variable.

# include <iostream.h>
# include <conio.h>


class A
{
public :
int x;
int y;
int z;
};

void main( )
{
clrscr( );
  A a;
  int *p;
  a.x=5;
  a.y=10;
  a.z=15;
  p=&a.x;
  cout<<endl<<"x= "<<*p;
  p++;
  cout<<endl<<"y= "<<*p;
  p++;
  cout<<endl<<"z= "<<*p;
}

OUTPUT

x= 5

y= 10

z= 15

Explanation: In the above program the class A is declared with three public member variables x, y and z. In function main( ), a is an object of class A and p is an integer pointer. The three member variables are initialized with 5, 10 and 15 using assignment operation.

The address of variable x is assigned to a pointer. The postfix incrementation operation gives successive memory locations, and values stored at those locations are accessed and displayed. Thus, member variables are stored in successive memory locations. Using the same concept we can also access private members.

10.10 ACCESSING PRIVATE MEMBERS WITH POINTERS

In the last topic we learned how to access public members of a class using pointers. The public and private member variables are stored in successive memory locations. The following program explains how private members can also be accessed using pointer.

10.20 Write a program to access private members like public members of the class using pointers.

# include <iostream.h>
# include <conio.h>


class A

{
private:
int j;
public :
int x;
int y;
int z;
A ( ) { j=20;}
};


void main( )
{
  clrscr( );
  A a;
  int *p;
  a.x=11;
  a.y=10;
  a.z=15;
  p=&a.x;
  p--;
  cout<<endl<<"j ="<<*p;
  p++;
  cout<<endl<<"x= "<<*p;
  p++;
  cout<<endl<<"y= "<<*p;
  p++;
  cout<<endl<<"z= "<<*p;
}

OUTPUT

j =20

x= 11

y= 10

z= 15

Explanation: This program is the same as the last one. In addition, the class A has one private member variable. The private member variables can be accessed using functions and no direct access is possible to them. However, using pointers we can access them like public member variables.

10.11 DIRECT ACCESS TO PRIVATE MEMBERS

So far, we have initialized private members of the class using constructor or member function of the same class. In the last sub-topic we also learned how private members of the class can be accessed using pointers. In the same way, we can initialize private members and display them. Obtaining the address of any public member variable and using address of the object one can do this. The address of the object contains address of the first element. Programs concerning this are explained below:

10.21 Write a program to initialize the private members and display them without the use of member functions.

# include <iostream.h>
# include <conio.h>


class A
{
  private :
  int x;
  int y;
};



void main( )
{
  clrscr( );
     A a;
     int *p=(int*)&a;
     *p=3;
     p++;
     *p=9;
     p--;
     cout <<endl <<"x= "<<*p;
     p++;
     cout <<endl<<"y= "<<*p;
}

OUTPUT

x= 3

y= 9

Explanation: In the above program, a is an object of class A. The address of the object is assigned to integer pointer p applying typecasting. The pointer p points to private member x. Integer value is assigned to *p i.e., x. By increase, operation next memory location is accessed and nine is assigned i.e., y. The p- - statement sets memory location of x using cout statement and contents of pointer is displayed.

10.12 ADDRESS OF OBJECT AND VOID POINTERS

The size of object is equal to number of total member variables declared inside the class. The size of member function is not considered in object. The object itself contains address of first member variable. By obtaining the address we can access the member variables directly, no matter whether they are private or public. The address of object cannot be assigned to the pointer of the same type. This is because increase operation on pointers will set the address of object according to its size (size of object=size of total member variables). The address of object should be increased according to the basic data type. To overcome this situation a void pointer is useful. The type of void pointer can be changed at run-time using typecasting syntax. Thus, all the member variables can be accessed directly. Consider the following program:

10.22 Write a program to declare void pointers and access member variables using void pointers.

# include <iostream.h>
# include <conio.h>
# include <stdio.h>



class A
{
  protected:
  int x;
  int y;


};
class B : public  A
{
  public :
  int z;
  B ( ) { x=10; y=20; z=30;}


};


void main ( )

{
  clrscr( );          // clears the screen
  B b;               // object declaration
  int j;             //  declaration of integer j
  void  *p=&b;       // declaration  & initialization of void pointer
  for (j=0;j<3;j++)  // for loop executed for three times
  printf ("\n member variable [%d] =  %d",j+1,*((int*)p+j));
  // cout<<j+1<<"  " <<*((int*)p+j)<<endl;
}

OUTPUT

member variable [1] = 10

member variable [2] = 20

member variable [3] = 30

Explanation: In the above program, b is an object of derived class B. The address of object b is assigned to void pointer p. Using for loop and typecasting operation, integer values are accessed. The address of void pointer is increased by two bytes. The cout statement now and then will not display the result properly and hence, the printf( ) statement is used.

The typecasting operation is done according to the data type of member variables. Here, all the class member variables are of integer type. In case, the class contains variables of integer, float and char type, then it is necessary to typecast according to the sequence of the member variables.

10.13 ARRAYS

ARRAYS

Array is a collection of elements of similar data types in which each element is unique and located in separate memory locations.

(1) Array Declaration and Initialization

Declaration of an array is shown below:

Declaration

int a [5];

It tells to the compiler that ‘a’ is an integer type of array and it must store five integers. The compiler reserves two bytes of memory for each integer array element. In the same way array of different data types are declared as below:

Array Declaration

char ch [10];

float real [10];

long num [5];

The array initialization is done as given below:

Array Initialization

int a [5]={1,2,3,4,5};

Here, five elements are stored in an array ‘a’. The array elements are stored sequentially in separate locations. Then question arises how to call individually to each element from this bunch of integer elements. Reading of array elements begins from zero.

Array elements are called with array name followed by element numbers. Table 10.1 explains the same.

Table 10.1 Calling array elements

a[0] refers to 1st element i.e. 1
a[1] refers to 2nd element i.e. 2
a[2] refers to 3rd element i.e. 3
a[3] refers to 4th element i.e. 4
a[4] refers to 5th element i.e. 5

10.14 CHARACTERISTICS OF ARRAYS

(1) The declaration int a[5] is nothing but creation of five variables of integer type in memory. Instead of declaring five variables for five values, the programmer can define them in an array.

(2) All the elements of an array share the same name, and they are distinguished from one another with the help of element number.

(3) The element number in an array plays major role in calling each element.

(4) Any particular element of an array can be modified separately without disturbing other elements.
int a [5]={1,2,3,4,8};
If the programmer needs to replace 8 with 10, he/she is not required to change all other numbers except 8. To carry out this task the statement a[4]=10 can be used. Here the other three elements are not disturbed.

(5) Any element of an array a[] can be assigned/equated to another ordinary variable or array variable of its type.

For example

b= a [2];

a [2]=a [3];

(a) In the statement b= a[2] or vice versa, value ofa[2] is assigned to b, where b is an integer.

(b) In the statement a[2]=a[3] or vice versa, value of a[2] is assigned to a[3], where both the elements are of the same array.

(6) The array elements are stored in continuous memory locations. The amount of storage required for holding elements of the array depends upon its type and size. The total size in bytes for a single dimensional array is computed as shown below.

Total bytes = sizeof(data type) X size of array

The rules for array declaration are the same in C and C++. The only difference is in the declaration of strings i.e., character array.

Program executed in C Program executed in C++
# include <stdio.h>
# include <conio.h>


void main( )
{
char text[3]="xyz";
char txt[3]="abc";
clrscr( );
printf ("\n %s",text);
printf ("%s", text)
}
# include <stdio.h>
# include <conio.h>


void main( )
{
char text[3]="xyz";
char txt[3]="abc";
clrscr( );
printf ("\n %s",text);
printf ("%s", text)
}

OUTPUT OUTPUT
xyz_abcW__ xyzA

Explanation: Both the above programs are same. The same programs are executed in C(Ver 2.0) and C++(ver 3.0). The character arrays are declared exactly equal to the length of the string. The account of null character is not taken. That’s why in C the printf( ) statement displays the contents of the next character array followed by the character array. In C++, the printf( ) statement displays one garbage value followed by the original string. This is so far the difference of string initialization in C and C++. It is a better practice to always count an account of null characters. Thus, the above character arrays can be correctly declared as below:

(a) char text [4]=“xyz”;

(b) char txt [4]=“abc”;

Now the correct output can be obtained.

10.15 INITIALIZATION OF ARRAYS USING FUNCTIONS

The programmers always initialize the array using statement like int d[ ]={1,2,3,4,5}. Instead of this the function can also be directly called to initialize the array. The program given below illustrates this point.

10.23 Write a program to initialize an array using functions.

# include <stdio.h>
# include <conio.h>
main( )
{
int k,c( ),d[]={c( ),c( ),c( ),c( ),c( )};
clrscr( );
printf ("\n Array d[] elements are :");
for (k=0;k<5;k++)
printf ("%2d",d[k]);



return (NULL);
}


c( )
{
static int m,n;
m++;
printf ("\nEnter Number d[%d] : ",m);
scanf ("%d",&n);
return(n);


}

OUTPUT:

Enter Number d[1] : 4

Enter Number d[2] : 5

Enter Number d[3] : 6

Enter Number d[4] : 7

Enter Number d[5] : 8

Array d[] elements are : 4 5 6 7 8

Explanation: Function can be called in the declaration of arrays. In the above program, d[ ] is an integer array and c( ) is a user-defined function. The function c( ) when called reads value through the keyboard. The function c( ) is called from an array i.e., the values returned by the function are assigned to the array. The above program will not work in C.

10.16 ARRAYS OF CLASSES

We know that array is a collection of similar data types. In the same way, we can also define array of classes. In such type of array, every element is of class type. Array of class objects can be declared as shown below:

class stud
{
  public:
  char name [12];       // class declaration
  int rollno;
  char grade[2];
};


class stud st[3];       // declaration of array of class objects

In the above example, st[3] is an array of three elements containing three objects of class stud. Each element of st[3] has its own set class member variables i.e., char name[12], int rollno and char grade[2]. A program is explained as given below:

10.24 Write a program to display names, rollnos, and grades of 3 students who have appeared in the examination. Declare the class of name, rollnos, and grade. Create an array of class objects. Read and display the contents of the array.

# include <stdio.h>
# include <conio.h>
# include <iostream.h>
void main( )
{
int k=0;
class stud
{
public :
char name[12];
int rollno;
char grade[2];
};


class stud st[3];
while (k<3)
{clrscr( );
    gotoxy(2,4);
    cout <<"Name     : ";
    gotoxy(17,4);
    cin >>st[k].name;


    gotoxy(2,5);
    cout <<"Roll No. : ";

    gotoxy(17,5);
    cin >>st[k].rollno;
    gotoxy(2,6);
    cout <<"Grade    :";
    gotoxy(17,6);
    cin>>st[k].grade;
    st[k].grade[1]='\0';
    puts ("   press any key..");
    getch( );
    k++;
}
    k=0;
    clrscr( );
    cout<<"\nName\tRollno Grade\n";
    while (k<3)
    {
    cout<<st[k].name<<"\t"<<st[k].rollno<<" \t"<<st[k].grade<<"\n";
    k++;
}
}

OUTPUT

 

Name    Rollno    Grade

Balaji    50    A

Manoj    51    B

Sanjay    55    C

Explanation: In the above program, class stud is declared. Its members are char name[12]; int rollno and char grade[2] and all are public. The array st[3] of class stud is declared. The first while loop and cin( ) statements within the first while loop are used for repetitive data reading. The second while loop and printf( ) statements within it display the contents of array. In the above program all the member variables are public. If the member variables are private, the above program will not work. Then, we need to declare member functions to access the data.

SUMMARY

(1) Like C, in C++ variables are used to hold data values during program execution. Every variable when declared occupies certain memory locations.

(2) Pointer saves the memory space. The execution time with pointer is faster because data is manipulated with the address.

(3) The indirection operator (*) is also called the deference operator. When a pointer is dereferenced, the value at that address stored by the pointer is retrieved.

(4) The & is the address operator and it represents the address of the variable. The address of any variable is a whole number.

(5) Pointers can also be declared as void type. Void pointers cannot be dereferenced without explicit type conversion. This is because being void the compiler cannot determine the size of the object the pointer points to.

(6) The pointer this is transferred as an unseen parameter in all calls to non-static member functions. The keyword this is a local variable, always present in the body of any non-static member function.

(7) Array is a collection of similar data types in which each element is a unique one and located in separate memory locations.

(8) The array elements are stored in continuous memory locations. The amount of storage required for holding elements of an array depends upon its type and size.

EXERCISES

[A] Answer the following questions.

(1) What are pointers?

(2) What is void pointer?

(3) What is wild pointer?

(4) What is this pointer?

(5) What are the features and uses of pointers?

(6) In which situation does the pointer become harmful?

(7) Explain any two characteristics of pointers.

(8) What are arrays?

(9) How can array initialization be carried out using function?

(10) Explain any three characteristics of arrays.

(11) How can private members be accessed using pointers?

(12) Why is declaration of void variable not permitted?

[B] Answer the following by selecting the appropriate option.

(1) The pointer holds

(a) address of the variable

(b) value of the variable

(c) both (a) & (b)

(d) none of the above

(2) An integer type pointer can hold only address of

(a) integer variable

(b) float variable

(c) any variable

(d) none of the above

(3) The address of the variable is displayed by the symbol

(a) & (ampersand)

(b) * (asterisk)

(c) (not operator)

(d) new operator

(4) The sizeof( ) object is equal to

(a) total size of data member variables

(b) total size of member functions

(c) size of large element

(d) none of the above

(5) Array elements are stored in

(a) continuous memory locations

(b) different memory locations

(c) CPU registers

(d) none of the above

(6) Private member variables can be accessed directly using

(a) pointers

(b) arrays

(c) this pointer

(d) none of the above

(7) The object itself is a

(a) pointer

(b) variable

(c) class member

(d) none of the above

(8) The size of void pointers is

(a) 2 bytes

(b) 0 bytes

(c) 4 bytes

(d) none of the above

(9) The this is present in every

(a) member function

(b) non-member function

(c) every object

(d) all of the above

(10) The array name itself is a

(a) pointer

(b) reference

(c) variable

(d) object

(11) In the following program the statement a=&(b=&x);

void main ( )
{
    int x=10;
    int **a,*b;
    a=&(b=&x);
    cout<<"x="<<**a;
    cout<<"\nx="<<*b;
}

(a) address of b is assigned to a

(b) address of x is assigned to a

(c) pointer a points to b

(d) both (a) and (c)

[C] Attempt the following programs.

(1) Write a program to declare integer pointer. Store 10 numbers in the pointer. Use new operator to allocate memory for 10 integers. Read and display the numbers.

(2) Try the above program without allocating memory. Use increment operator to get successive location in the memory. While displaying numbers, retrieve previous memory locations using decrement operator. (Tip: The program without new operator shows warnings, for the time being ignore it, but in practical application new operator is essential)

(3) Write a program to declare float and integer arrays. Read five float numbers. Separate integer and fractional parts. Store the integers separated in integer array and fractional in float array. Display the contents of both the arrays.

(4) Write a program to find the determinant of a 2 X 2 matrix using pointers.
B(1,1) B(1,2)
B(2,1) B (2,2)
The determinant of the matrix is B (1,1)*B (2,2)-B (1,2)*B (2,1).

(5) Write a program to find the number of zero elements in 3 X 3 matrix. Read and display the element. Also, write this program using pointers.

(6) The table given below gives the sales of four items of a shop.

(a) Calculate the total daily sales per day.

(b) Calculate the weekly sales of each item.

(c) Calculate the average daily sales of each item.

(d) Calculate the total weekly sales of the shop.

(7) Write a program to find the sum of diagonal elements of 3 X 3 matrix.

(8) Write a program to declare array of character type. Store ten names in array. Display the names in ascending order.

(9) Write a program to declare two pointers to the same variable. Display the values of variable using both the pointers.

(10) Write a program to declare an integer array. Display the contents of array using pointer.

[D] Find bugs in the following programs.

(1)

class set
{  int x; };


void main( )
{
    set a;
    cout <<endl<<(unsigned)&a.x;
}

(2)

void main ( )
{
    int x=20;
    float *p;
    p=&x;
    cout<<x;
}

(3)

void main ( )
{
    void y(int);
    y =30;
    cout<<y;
}

(4)

void main ( )
{
    void *y;
    (int) y =30;
    cout<<(unsigned)y;
}

(5)

void main ( )
{      char *x;
    int u=10;
    x=&u;
}

(6)

void main ( )
{
    int x=10;
    int *a,*b;
    a=&(b=&x);
    cout<<"x="<<*a;
    cout<<"\nx="<<*b;
}