home *** CD-ROM | disk | FTP | other *** search
-
-
-
- Chapter 3
- POINTERS
-
- Because pointers are so important in C and C++, this chapter will
- review some of the more important topics concerning pointers.
- Even if you are extremely conversant in the use of pointers, you
- should not completely ignore this chapter because some new
- material unique to C++ is presented here.
-
-
- POINTER REVIEW
- -----------------------------------------------------------------
- Examine the program named POINTERS.CPP for a ==================
- simple example of the use of pointers. This POINTERS.CPP
- is a pointer review and if you are ==================
- comfortable with the use of pointers, you can
- skip this example program completely. A pointer in either ANSI-C
- or C++ is declared with an asterisk preceding the variable name.
- The pointer is then a pointer to a variable of that one specific
- type and should not be used with variables of other types. Thus
- pt_int is a pointer to an integer type variable and should not be
- used with any other type. Of course, an experienced C programmer
- knows that it is simple to coerce the pointer to be used with
- some other type by using a cast, but he must then assume the
- responsibility for its correct usage.
-
- In line 12 the pointer named pt_int is assigned the address of
- the variable named pig and line 13 uses the pointer named pt_int
- to add the value of dog to the value of pig because the asterisk
- dereferences the pointer in exactly the same manner as standard
- C. The address is used to print out the value of the variable
- pig in line 14 illustrating the use of a pointer with the stream
- output operator cout. Likewise, the pointer to float named
- pt_float is assigned the address of x, then used in a trivial
- calculation in line 18. Figure 3-1 is a graphical representation
- of the data space following execution of line 13. Note that a
- box containing a dot represents a pointer.
-
- If you are not completely comfortable with this trivial program
- using pointers, you should review the use of pointers in any good
- C programming book or Coronado Enterprises C tutorial before
- proceeding on because we will assume that you have a thorough
- knowledge of pointers throughout the remainder of this tutorial.
- It is not possible to write a C program of any significant size
- or complexity without the use of pointers.
-
-
- CONSTANT POINTERS AND POINTERS TO CONSTANTS
- -----------------------------------------------------------------
- The definition of C++ allows a pointer to a constant to be
- defined such that the value to which the pointer points cannot be
- changed but the pointer itself can be moved to another variable
-
- Page 3-1
-
- Chapter 3 - Pointers
-
- or constant. The method of defining a pointer to a constant is
- illustrated in line 22. In addition to a pointer to a constant,
- you can also declare a constant pointer, one that cannot be
- changed. Line 23 illustrates this. Note that neither of these
- pointers are used in illustrative code.
-
- Either of these constructs can be used to provide additional
- compile time checking and improve the quality of your code. If
- you know a pointer will never be moved due to its nature, you
- should define it as a constant pointer. If you know that a value
- will not be changed, it can be defined as a constant and the
- compiler will tell you if you ever inadvertently attempt to
- change it.
-
-
- A POINTER TO VOID
- -----------------------------------------------------------------
- The pointer to void is actually a part of the ANSI-C standard but
- is relatively new so it is commented upon here. A pointer to
- void can be assigned the value of any other pointer type. You
- will notice that the pointer to void named general is assigned an
- address of an int type in line 15 and the address of a float type
- in line 20 with no cast and no complaints from the compiler.
- This is a relatively new concept in C and C++. It allows a
- programmer to define a pointer that can be used to point to many
- different kinds of things to transfer information around within a
- program. A good example is the malloc() function which returns a
- pointer to void. This pointer can be assigned to point to any
- entity, thus transferring the returned pointer to the correct
- type.
-
- A pointer to void is aligned in memory in such a way that it can
- be used with any of the simple predefined types available in C++,
- or in ANSI-C for that matter. They will also align with any
- compound types the user can define since compound types are
- composed of the simpler types.
-
- Be sure to compile and execute this program.
-
-
- DYNAMIC ALLOCATION AND DEALLOCATION
- -----------------------------------------------------------------
- Examine the program named NEWDEL.CPP for our ==================
- first example of the new and delete operators. NEWDEL.CPP
- The new and delete operators do dynamic ==================
- allocation and deallocation in much the same
- manner that malloc() and free() do in your old favorite C
- implementation.
-
- During the design of C++, it was felt that since dynamic
- allocation and deallocation are such a heavily used part of the C
- programming language and would also be heavily used in C++, it
- should be a part of the language, rather than a library add-on.
-
- Page 3-2
-
- Chapter 3 - Pointers
-
- The new and delete operators are actually a part of the C++
- language and are operators, much like the addition operator or
- the assignment operator. They are therefore very efficient, and
- are very easy to use as we will see in this example program.
-
- Lines 14 and 15 illustrate the use of pointers in the tradition
- of C and line 16 illustrates the use of the new operator. This
- operator requires one modifier which must be a type as
- illustrated here. The pointer named point2 is now pointing at
- the dynamically allocated integer variable which exists on the
- heap, and can be used in the same way that any dynamically
- allocated variable is used in ANSI-C. Line 18 illustrates
- displaying the value on the monitor which was assigned in line
- 17.
-
- Line 20 allocates another new variable and line 21 causes point2
- to refer to the same dynamically allocated variable as point1 is
- pointing to. In this case, the reference to the variable that
- point2 was previously pointing to has been lost and it can never
- be used or deallocated. It is lost on the heap until we return
- to the operating system when it will be reclaimed for further
- use, so this is obviously not good practice. Note that point1 is
- deallocated with the delete operator in line 25, and point2 can
- not be deleted since it is now pointing to nothing. Since the
- pointer point1 itself is not changed, it is actually still
- pointing to the original data on the heap. This data could
- probably be referred to again using point1, but it would be
- terrible programming practice since you have no guarantee what
- the system will do with the pointer or the data. The data
- storage is returned to the free list to be allocated in a
- subsequent call, and will soon be reused in any practical
- program.
-
- Since the delete operator is defined to do nothing if it is
- passed a NULL value, it is legal to ask the system to delete the
- data pointed to by a pointer with the value of NULL, but nothing
- will actually happen. It is actually wasted code. The delete
- operator can only be used to delete data allocated by a new
- operator. If the delete is used with any other kind of data, the
- operation is undefined and anything can happen. According to the
- ANSI standard, even a system crash is a legal result of this
- illegal operation, and can be defined as such by the compiler
- writer.
-
- In line 27, we declare some floating point variables. You will
- remember that in C++ the variables do not have to be declared at
- the beginning of a block. A declaration is an executable
- statement and can therefore appear anywhere in a list of
- executable statements. One of the float variables is allocated
- within the declaration to illustrate that this can be done. Some
- of the same operations are performed on these float type
- variables as were done on the int types earlier.
-
-
- Page 3-3
-
- Chapter 3 - Pointers
-
- Some examples of the use of a structure are given in lines 35
- through 41 and should be self explanatory.
-
- Finally, since the new operator requires a type to determine the
- size of the dynamically allocated block, you may wonder how you
- can allocate a block of arbitrary size. This is possible by
- using the construct illustrated in line 47 where a block of 37
- char sized entities, which will be 37 bytes, is allocated. A
- block of 133 bytes greater than the size of the date structure is
- allocated in line 49. It is therefore clear that the new
- operator can be used with all of the flexibility of the malloc()
- function which you are familiar with. The brackets are required
- in lines 48 and 50 to tell the compiler that it is deallocating
- an array.
-
- The standard functions which you have been using in C for dynamic
- memory management, malloc(), calloc(), and free(), are also
- available for use in C++ and can be used in the same manner they
- were used in C. The new and delete operators should not be
- intermixed with the older function calls since the results may be
- unpredictable. If you are updating code with the older function
- calls, continue to use them for any additions to the code. If
- you are designing and coding a new program you should use the
- newer constructs because they are a built in part of the language
- rather than an add on and are therefore more efficient.
-
- Be sure to compile and execute this program.
-
-
- POINTERS TO FUNCTIONS
- -----------------------------------------------------------------
- Examine the program named FUNCPNT.CPP for an =================
- example of using a pointer to a function. It FUNCPNT.CPP
- must be pointed out that there is nothing new =================
- here, the pointer to a function is available
- in ANSI-C as well as in C++ and works in the manner described
- here for both languages. It is not regularly used by most C
- programmers, so it is briefly discussed here as a refresher. If
- you are comfortable with the use of pointers to functions, you
- can skip this discussion entirely.
-
- There is nothing unusual about this program except for the
- pointer to a function declared in line 7. This declares a
- pointer to a function which returns nothing (void) and requires a
- single formal parameter, a float type variable. You will notice
- that all three of the functions declared in lines 4 through 6 fit
- this profile and are therefore candidates to be called with this
- pointer. If you have not used prototyping in C, these lines will
- look strange to you. Don't worry about them at this point since
- we will study prototyping in the next chapter of this tutorial.
-
- Observe that in line 14 we call the function print_stuff() with
- the parameter pi and in line 15 we assign the function pointer
-
- Page 3-4
-
- Chapter 3 - Pointers
-
- named function_pointer the value of print_stuff() and use the
- function pointer to call the same function again in line 16.
- Lines 14 and 16 are therefore identical in what is accomplished
- because of the pointer assignment in line 15. In lines 17
- through 22, a few more illustrations of the use of the function
- pointer are given. You will be left to study these on your own.
-
- Since we assigned the name of a function to a function pointer,
- and did not get an assignment error, the name of a function must
- be a pointer to that function. This is exactly the case. A
- function name is a pointer to that function, but it is a pointer
- constant and cannot be changed. This is exactly the case we
- found when we studied arrays in ANSI-C at some point in our C
- programming background. An array name is a pointer constant to
- the first element of the array.
-
- Since the name of the function is a constant pointer to that
- function, we can assign the name of the function to a function
- pointer and use the function pointer to call the function. The
- only caveat is that the return value and the number and types of
- parameters must be identical. Most C and C++ compilers will not,
- and in fact, can not warn you of type mismatches between the
- parameter lists when the assignments are made. This is because
- the assignments are done at runtime when no type information is
- available to the system, rather than at compile time when all
- type information is available.
-
- The use and operation of pointers must be thoroughly understood
- when we get to the material on dynamic binding and polymorphism
- later in this tutorial. It will be discussed in detail at that
- time.
-
- Be sure to compile and execute this program.
-
-
- PROGRAMMING EXERCISES
- -----------------------------------------------------------------
- 1. When dynamically allocated data is deleted, it is still
- actually in memory, stored on the heap. Repeat the output
- statement from line 23 of NEWDEL.CPP immediately following
- the delete in line 25 to see if the values are really still
- there. Repeat it once again just prior to the end of the
- program when the data spaces should have been written over to
- see if you get garbage out. Even if your compiler reports
- the correct data, it is terrible practice to count on this
- data still being there because in a large dynamic program,
- the heap space will be used repeatedly.
-
- 2. Add a function to FUNCPNT.CPP which uses a single integer for
- a parameter and attempt to call it by using the function
- pointer to see if you get the correct data into the function.
-
-
-
- Page 3-5
-