POINTERS


               5.1 Introduction:

               Pointers are variables that hold address values.  Pointers are defined using an asterisk (*) to 
               mean pointer to. A data type is always included in pointer definitions, since the compiler must 
               know what is being pointed to, so that it can perform arithmetic correctly on the pointer.   We 
               access the thing pointed to using the asterisk in a different way, as the indirection operator,
               meaning contents of the variable pointed to by. 
               5.2 Addresses and Pointers:
               The ideas behind pointers are not complicated. Here's the first key concept: Every byte in  the 
               computer's memory has an address. Addresses are numbers,just as they are for houses on a street. 
               The numbers start at 0 and go up from there-l, 2, 3, and so on. If you have 640K of memory, the 
              highest address is 655,359; for 1 MB of memory, it is 1,048,575.

               

               Your program, when it is loaded into memory, occupies a certain range of these addresses. That 

               means that every variable and every function in your program starts at a particular address.

               

               2.3 The Address Of Operator &:

 

               You can find out the address occupied by a variable by using the address of operator &. 

               Here's a short program that demonstrates this: 

                               

               // address of variables 

               # include< iostream.h> 

               void main ( )

               {

                    int var1 = 11;                    // define and initialize 

                    int var2 = 22;                    // three variables 

                    int var3 = 33;

                

                    cout << endl << &var1     // print out the addresses 

                            << endl << &var2     // of these variables 

                               << endl << &var3; 

               } 

               

               This simple program defines three integer, variables and initializes them to the values 11, 22, 

               and 33. It then prints out the addresses of these variables. The actual addresses occupied by the

               variables in a program depend on many factors, such as the computer the program is running on, 

               the size of the operating system, and whether any other programs are currently in memory. 

               For these reasons you probably won't get the same addresses we did when you run this program.

               

               Here's the output on our machine: 

               

               Ox8f4ffff4                               address of varl 

               Ox8f4ffff2                               address of var2 

               Ox8f4ffffO                              address of var3 

 

               The address of a variable is not  at all the  same as  its contents. The contents of the  three 

               variables are 11,22, and 33. The << insertion  operator  interprets the addresses in hexadecimal 

               arithmetic,as indicated by the prefix Ox before each number.This is the usual way to show memory 

               addresses. 

                               

               The addresses appear in descending order because automatic variables are stored on the stack, which 

               grows downward in memory. If we had used external variables they would have ascending addresses, 

               since external 

               variables are stored on the heap, which grows upward.

               

               2.4 Pointer Variable:

               

               Address by themselves are rather limited.It's nice to know that we can find out where things are in 

               memory,but printing out address values is not all that useful. The potential for increasing our

               programming power requires an additional idea: variables that hold address values. Addresses are stored 

               similarly as variables of different data types.A variable that holds an address value is called a 

               pointer variable or simply a pointer.

               

               2.5 Declaring and Initializing Pointers: 

               

               Let's examine the process of declaring pointers. A computer needs to keep  track of the type of value

               to which a pointer refers. For example,the address of a char looks the same as the address of a double,

               but char and double use  different  numbers of bytes and different internal formats for storing values. 

               Therefore, a  pointer declaration  must  specify what  type of data it is to which the pointer points. 

               For example, the statement. 

               

                               int  * p_updates; 

               

               This states that the combination * p-updates is type int. Because the * operator is 

               used by applying it to a pointer, the p_updates variable itself must be a pointer. We say that

               p_updates points to type int. We also say that the type for p_updates is pointer-to-int or,more concisely,

               int *. To repeat p_updates is a pointer (an address}, and *p-updatesis an int and not a 

               pointer.

                

               Incidentally, the use of spaces around the * operator are optional. For example: 

               

                               int* ptr;

               

               This emphasizes the idea that int* is a type, pointer-to-int. Where you put the spaces makes no

               difference to the compiler. Be aware, however, that the declaration

               

                               int* p1,p2;

 

               Creates one pointer (p1) and one ordinary int variable (p2)

               If you define more than  one pointer of  the same  type on one line,  you need  only insert the 

               type-pointed-to once, but you need to place an asterisk before each variable name:
              

                               char * ptr1, * ptr2, * ptr3;      // three variables of type char*

               

               Or you can use the asterisk-next-to-the-name approach 

               

                               char *ptr1, *ptr2, *ptr3;         // three variables of type char* 

               

               Pointers Must Have a Value: An address like OxHf4ffff4 can be thought of as a pointer constant.

               A pointer like ptr can be thought of as a pointer variable.Just as the integer variable var1 can

               be assigned the constant value 11, so can the pointer variable ptr be assigned the constant value 

               Ox8f4ffff4.

               

               When we first define a variable, it holds no value (unless we initialize it at the same time) it 

               may hold a garbage value, but this has no meaning. In the case of pointers, a garbage value is the 

               address of something in memory,but probably not of something that we want.So before a pointer is 

               used,a specific address must be placed in it. 

 

                               ptr = &var1;                           put address of var l in ptr. 

               

               Following this the program prints out the value contained in ptr,which should be the same address 

               printed for &var1.

                

               To summarize:A pointer can hold the address of any variable of the correct type; However, it 

               must be given some value, otherwise it will point to an address we don't want it to point to, such 

               as into our program code or the operating system. Wrong pointer values can result in system crashes 

               and are difficult to debug, since the compiler gives no warning.              

               

               2.6 Accessing the Variable Pointed to:

               

               Suppose that we don't know the name of a variable but we do know its address. We can access the 

               contents of the variable, by using a special syntax (indirection operator)to access the value of such 

               variable.

                                

               # include < iostream.h> 

               

               void main( )  

               {

                               int var1 =11;                          //two integer variables

                               int var2 = 22;

                               int* ptr;                   // pointer  to integers

                               ptr = &var1;                           // pointer points to var1

                               cout << endl<< *ptr;              // pointer contents of pointer (11)

                               ptr = &var2;                           // pointer points to var2

                               cout << endl << *ptr;             // pointer contents of pointer (22)

               }

               

               When an asterisk is used in front of a variable name, as it is in the * ptr  expression; it is called 

               the indirection operator. It means  the value of  variable  pointed to by.  Thus the expression *ptr 

               represents the value of the variable pointed to by ptr. When ptr is set to the address of var1, the 

               expression *ptr has the value 11; since var1 is 11. When ptr is changed to the address of var2, the 

               expression *ptr acquires the value 22, since var1  is 22.You can use a pointer not only to display a

               variable's value but to perform  any operation you  would perform on the variable directly. The 

               asterisk used as the indirection operator has a different meaning from the  asterisk used to declare 

               pointer  variables.The  indirection o perator precedes the variable and means value of the variable 

               pointed to by the asterisk used in a declaration means pointer to.

                

                               int * ptr;   // declaration: 

                               *ptr =37;                // indirection: 

               

               Using the indirection operator to access the value stored in an address is called indirect 

               addressing, or sometimes dereferencing, the pointer:  

 

                               int  v;                      // defines variable v of type int 

                               int* p;                     // defines p as a pointer to int 

                               p = &v;   // assigns address of variable v to pointer p 

                               v = 3;                      // assigns 3 to v 

                               *p = 3;    // also assigns 3 to V 

                

               2.7 Pointers and Arrays:

               

               There is a close association between pointers and arrays. The near equivalence of pointers and 

               array names stems form the pointer arithmetic and how C++ handles arrays internally.
               Consider the program below:
              

              # include < iostream.h>
            

               void main( )

               { 

               

                    double wages[3] = {10000.0, 20000.0, 30000.0}; 

                    short stacks[3] = {3, 2, 1}; 

 

                     //Here are two ways to get the address of an array 

                     double * pw = wages;      // name of an array = address 

                     short * ps = &stacks[0];   // or use address operator

                

                    // with array element 

                    cout << "pw = " << pw << " *pw = " << *pw << "\n"; 

                      pw = pw + 1; 

                      cout << "add 1 to the pw pointer: \n'; 

                      cout << "pw = " << pw << ", *pw = " << *pw << "\n\n"; 

                      cout << "ps = " << ps << " *ps = " << *ps << "\n"; 

                      ps = ps + 1; 

               

                      cout << "add 1 to the ps pointer:\n"; 

                      cout << "ps = " << ps << ", *ps = " << *ps << "\n\n"; 

                      cout << "access two elements with array notation \n"; 

                      cout << stacks[0] << " " << stacks[1] << "\n"; 

                      cout << "access two elements with pointer notation \n"; 

                      cout << *stacks << " " << *(stacks + 1) << "\n"; 

                      cout << sizeof wages << " = size of wages array \n"; 

                      cout << sizeof pw << " = size of pw pointer \n"; 

               } 

               

               C++ interprets the name of an array as the, address of its first element. Thus, the statement 

               

               double * pw = wages; 

 

               makes pw a pointer to type double and then initializes pw to wages, which is the address of the first

               element of the wages array. For wages, as with any array, we have the following equality: 

               

                               wages = &wages[0] = address of first element of array 

               

               Just to   show  that this  is no jive, the  program explicitly uses the address operator in the expression 

               &stacks [0] to  initialize  the ps  pointer to the first element of the stacks array. Next, the program 

               inspects the values of pw and *pw. The first is an address and the  second is the value at that address.

               Because pw points to the first element, the value  displayed for *pw is that of the first element, 10000. 

               Then, the program adds 1 to pw.  This adds 8 (EO + 8 = E8 in hexadecimal) to the numeric address value,

               because double is 8 bytes. This makes pw equal to the address of the second  element. Thus, *pw  now is 

               20000,  the value of the second element. After this, the program goes through similar steps for ps. This 

               time, because ps points to type short and because short is 2 bytes, adding 1 to the pointer increases its

               value by 2. Again, 

               the result is to make the pointer point to the next element of the array. 

               

               Note: Adding 1 to a pointer variable increases its value by the number of bytes of the type to which it 

               points. 

               

               2.8 Pointers and Strings: 

               

               The special relationship between arrays and pointers extends to strings. Consider the following code: 

               

                               char flower[10] = "rose"; 

                               cout << flower << "s are red \n"; 

               

               The name of an array is the address of its first element, so flower in the cout statement is the address of 

               the char element containing the character r. The cout object assumes that the address of a char is the 

               address of a string, so it prints the character at that address and then continues printing characters 

               until it runs into the null character (\0). In short, if you  give cout the address of  a character, it 

               prints everything from that character to the first null character that follows it. The crucial element here

               is not that flower is an array name but that flower acts as the address of a char. This implies that you can

               use a pointer-to-char variable as an argument to cout, also, because it, too,  is the  address of a char. Of  

               course, that pointer should point to the beginning of a string. We'll check that out in a moment. 

               

               But first, what about the final part of the preceding cout statement? If flower actually is the address of 

               the first character of a string, what is the expression "s are red\ n"? To be consistent with cout's handling

               of string output, this quoted string also should be an address. And it is, for in C++ a quoted string, like an 

               array name, serves as  the  address of its  first element. The preceding code doesn't really send a whole 

               string to cout, it just sends the string address.This means strings in an array; quoted string constants, and 

               strings described by pointers all are handled equivalently: Each really is passed along an address. That's 

               certainly less work than passing each and every character in a string.

               

               // Program to demonstrate arguments passed by pointer 

               #include < iostream.h> 

               void main( ) 

               { 

                               void centimize(double*);                        // prototype 

                               double var = 10.0;                                 // var has value of 10 inches 

                               cout << endl << "var=" << var << " inches"; 

 

                               centimize( &var);                                   // change var to centimeters 

                               cout << endl <<"var:" << var <<"centimeters" ; 

               } 

                               

               void centimize(double* ptrd) 

               { 

                               *ptrd *= 2.54;                                       // *ptrd is the same as var

               }

 

               The function centimize ( ) is declared as taking an argument that is a pointer to double: 

 

                               void centimize(double*)                         // argument is pointer to double 

               

               When main( ) calls the function it supplies the address of the variable as the argument: 

               

                               centimize(&var); 

               

               Remember that this is not the variable itself, as it is in passing by reference, but the variable's 

               address. 

               

               Because the centimize ( ) function is passed an address, it must use the indirection operator, *ptrd, 

               to access the value stored at this address:

                

                               *ptrd *= 2.54;                       // multiply the contents of ptrd by 2.54

               

               Is the same as 

               

                               *ptrd = *ptrd * 2.54;   // multiply the contents of ptrd by 2.54

               

               where the stand-alone asterisk means multiplication.

                

               Since ptrd contains the address of var, anything done to *ptrd is actually done to var. Passing a 

               pointer as an argument to a function is in some ways similar to passing a reference. They both permit 

               the  variable  in  the calling  program to be  modified by the function. However, the mechanism is  

               different. A  reference is an alias for the original variable,  while a pointer is the address of the 

               variable.  

        2.9 Using new to create Dynamic Structures:
        
               You've seen how it can be advantageous to create arrays during runtime rather than compile time.  

               The same holds true for structures. You need to allocate space for only as many structures as a 

               program needs during a particular run.  The new operator is the tool to use.  With it, you  can

               create dynamic structures. "Dynamic" means the memory is allocated during runtime, not during 

               compilation.Using new with structures has two parts: creating the structures and accessing its 

               members. To create a structure, use the structure type with new. For example, to create an unnamed

               structure and assign its address to a suitable pointer, you can do 

               the following: 

               

                               inflatable * ps = new inflatable;  // consider inflatable is am structure

               

               This assigns to ps the address of a chunk of free memory large enough to hold a structure of the

               inflatable  type. The tricky part is accessing members. When you create a dynamic structure, you 

               can't use the  dot membership operator with the structure name,because the structure has no name. 

               All you have is its address. C++ provides an operator just for this situation: the arrow membership

               operator(->).This operator, formed by typing a hyphen and then a greater-than symbol, does for 

               pointers to structures what the dot operator does for structure names. For example, if ps points

               to a type inflatable structure, then ps -> price is the price member of the pointed-to structure. 

               

               This operator obtains memory from the operating system and returns a pointer to its starting 

               point. Consider the program shows how new is used: 

               

               # include  

               # include                                // for strcpy() 

               void main( )

                { 

                     char* str = "Idle hands are the devil's workshop."; 

                     int len = strlen(str);                           // get length of str 

                     char* ptr;                                                        II make a pointer to char 

                     ptr = new char[len+1];                     // set aside memory: string + '\0' 

                      strcpy(ptr, str);                                               II copy str to new memory area ptr 

                      cout << endl << "ptr=" << ptr;        // show that str is now in ptr 

                      delete ptr;                                       // release ptr 's memory 

               } 

               

               The expression 

               

                               ptr = new char[len+1]; 

               

               returns a pointer that points to a section of memory just large enough to hold the string str,

               whose length len we found with the strlen ( ) library function, plus an extra byte for the null 

               character '\0' at the end of the string. Remember to use brackets around the size; the compiler 

               won't object if you use parentheses, but the results will be incorrect.

               

               2.10 Delete Operator:

 

               If your program reserves many chunks of memory using new, eventually all the available  memory 

               will be reserved and the system will crash. To ensure safe and efficient use of memory, a

               corresponding delete operator that returns memory to the operating system. 

               

                               delete ptr; 

               

               returns to the system whatever memory was pointed  to by ptr . Actually, there  is no need for 

               this operator, since memory is automatically returned  when the  program  terminates. However, 

               suppose you use new in a function. If the function uses a local variable  as  a pointer to this 

               memory, then when the function terminates, the pointer will be destroyed but the memory will be

               left as an orphan, taking up space that is inaccessible to the rest of the program. Thus it is 

               always good practice to delete memory when you're through with it. 

 

               5.11 Pointers to Objects:

 

               Pointers  can  point  to  objects as well as to simple data types. We've seen many examples of 

               objects defined and given a name, in statements like 

                               Distance dist; 

               

               where an object called dist is defined to be of the Distance class. Sometimes, however, we don't 

               know, at the time that we write the program, how many objects we want to create. When this is the 

               case we can use new to create objects while the program is running. 
               // Program to show accessing of member functions by pointer 

               # include < iostream.h> 

               class Distance         

               { 

                  private: 

                               int feet; 

                   float inches; 

                                              public:

                   void getdist( )                     // get length from user 

                   { 

                      cout << "\n Enter feet: ";   cin >> feet; 

                      cout << "Enter inches: ";    cin >> inches; 

                   } 

               

                   void showdist( )  // display distance 

                   {

                                 cout << feet <<"\'-" << inches << '\"'; 

                   } 

                  }; 

               

               void main( )

               { 

                               Distance dist;                                         // define a named Distance object 

                               dist.getdist( );                                         // access object members 

                               dist.showdist( );                      // with dot operator 

 

                               Distance*  distptr;                  // pointer to Distance 

                               distptr = new Distance;           // points to new Distance object 

                               distptr->getdist( );                  // access object members 

                               distptr->showdist( );                              // with -> operator 

               } 

               

               This program uses a variation of the Distance  class seen in  previous  chapters. The  main ( ) 

               function defines dist, uses the Distance member functions, getdist ( ) to get a distance from the

               user;  and then uses showdist ( ) to display it. 

               

               Referring To Members: The program creates another object of type Distance the new

               operator.To refer to a member function dot operator requires the identifier on its left to be a

               variable. We can deference (get the contents of the variable pointed to by) the pointer: 

               

                               (*distptr).getdist( );                                // ok but inelegant  

               

               However, this is slightly cumbersome because of the parentheses. A more concise approach is furnished 

               by the membership-access operator ->, which consists of a hyphen and a greater than sign: 

               

                               distptr->getdist( );                                  // better approach 

               

               Exercise:

               

               1• The structure candy contains three members. The first holds the name of the candy, the

               second holds the price (can be fractional) and the third holds the weight. Write a program that 

               creates a variable of candy using the new operator.

 

               2• Implement the concept of creating Linked list.

 

               3• Write a program to insert and delete a number in a linked list.

               

               4• Write a program to implement the stack, using pointer.