Depending on the type of the array elements and the sort crite-ria, the qsortfunction will expect as argument another comparison function.. 䊐 Declaring Pointers to Functions A pointer t
Trang 1䊐 Using Pointers to Functions
In C++ the name of a function is a constant pointer to that function It addresses the machine code for the function This is a situation that we have already seen for arrays— the array name is also a constant pointer to the first array element
There are many uses for pointers to functions You can save them in an array to form a
jump table Individual functions are then accessible via an index.
A pointer to a function can also be passed as an argument to another function This makes sense if the function you are calling needs to work with different functions depending on the current situation
The standard function qsort()is an example of this qsort()uses the quick sort algorithm to sort an array Depending on the type of the array elements and the sort
crite-ria, the qsort()function will expect as argument another comparison function
䊐 Declaring Pointers to Functions
A pointer to a function is declared as follows:
Syntax: type (* funcptr)( parameter_list );
This defines the variable funcptr, which can store the address of a function The func-tion has the type typeand the parameter list stated The first pair of parentheses is also important for the declaration The statement type *funcptr(parameter_list);
would declare a function funcptrthat returned a pointer
Now let’s point funcptrto the function compare()and call compare()via the pointer
Example: bool compare(double, double); // Prototype
bool (*funcptr)(double, double);
funcptr = compare;
(*funcptr)(9.1, 7.2);
Calling(*funcptr)()is now equivalent to calling compare() The declaration of
compare()is necessary to let the compiler know that compareis the name of a func-tion
In the program shown opposite, functabis an array with four pointers to functions
of the voidtype, each of which expects a C string as an argument functabis initial-ized by the functions stated in its definition and thus functab[0] points to
error_message(), functab[1] to message(), etc When the program is exe-cuted, the function with the specified index is called
Trang 2690 C H A P T E R 3 0 M O R E A B O U T P O I N T E R S
1 st Example:
3.
0 strptr is a
1 pointer to
2 an array with 50 elements of type
3 char.
1 0 2.
char (* strptr) [50]
2 nd Example:
5.
6 5 3 1 0 2 4.
0 func is a
1 function with return value of type
2 pointer to
3 an array with elements of type
4 pointer to
5 long.
0 funcptr is a
1 pointer to
2 a function with return value of type
3 pointer to
4 an array with elements of type
5 pointer to
6 char.
4 2 0 1.
long * (* func () ) []
3 rd Example: char * (* (* funcptr ) () ) []
3.
Trang 3Operator Significance
Array with elements of type
Function with return value of type
Pointer to
Reference to
[]
()
*
&
䊐 Operators and Complex Declarations
In the declaration and definition of a function or a variable the same operators that you find in expressions are used in addition to the base type and the name These operators are:
A complex declaration always uses more than one of these operators.
Example: char *strptr[50];
This declares strptras an array of pointers to char In a declaration, a combination of the three operators is permissible, however, the following exceptions apply:
■ the elements of an array cannot be functions
■ a function cannot return a function or an array (but it can return a pointer to a function or an array)
Operators have the same precedence in declarations as in expressions You can use parentheses to redefine the order of precedence
䊐 Rules
When a complex declaration is evaluated, the following rules are applied:
0 Always start with the identifier being declared
Then repeat the following steps until all the operators have been resolved:
1 If the parentheses/brackets ()or[]are on the right, they are interpreted.
2 If there is nothing or just a right bracket on the right ), the asterisk on the left is
interpreted, if it exists
At last the base type is interpreted
This proceeding is demonstrated by the example opposite The above rules apply to both the function and each of its arguments
Trang 4692 C H A P T E R 3 0 M O R E A B O U T P O I N T E R S
1st Example:
typedef DayTime FREETIME;
FREETIME timeArr[100];
2nd Example:
typedef struct { double re, im; } COMPLEX; COMPLEX z1, z2, *zp;
3rd Example:
typedef enum { Mo, Tu, We, Th, Fr } WORKDAY; WORKDAY day;
4th Example:
typedef enum { Diamonds, Hearts,
Spades, Clubs } COLOR;
typedef enum { seven, eight, nine, ten ,
jack, queen, king, ace } VALUE; typedef struct
{ COLOR f;
VALUE w;
} CARD;
typedef CARD[10] HAND;
HAND player1, player2, player3;
Trang 5䊐 The typedef Keyword
C++ allows you to give types a new name using the keyword typedef
Example: typedef unsigned char BYTE;
This defines the type name BYTE, which can then be used as an abbreviation of the
unsigned chartype The statement
Example: BYTE array[100];
will then define an array arraywith 100 elements of the unsigned chartype Type names are normally uppercase, although this is not mandatory
Examples: typedef int* INTPTR;
typedef enum{ RED, AMBER, GREEN } Lights;
Here,INTPTRidentifies the type “pointer to int” and Lightsis an enumerated type The new type name always assumes the position of a variable name in a typedef
definition Omitting the typedefprefix will define a variable name but not a new type name
Type definitions do not allocate memory and do not create a new type They simply introduce a new name for an existing type
Example: typedef char* (*PTR_TO_FUNC)();
The type name PTR_TO_FUNCis an abbreviation for the type “pointer to a function that returns a pointer to char.” The declaration
Example: PTR_TO_FUNC search;
is then equivalent to
char* (*search)();
䊐 Advantages
The major advantage of using typedefis that it improves the readability of your pro-grams, especially when complex types are named
One additional advantage is that you can isolate platform dependent types When a program is ported to another platform, you only need to change the platform dependent type once in the typedefdefinition
Trang 6694 C H A P T E R 3 0 M O R E A B O U T P O I N T E R S
// matrix.h: Representing dynamic matrices.
//
-#include <stdexcept>
#include <iostream>
using namespace std;
class Row
{ double *ro; int size;
public:
Row( int s) { size = s; ro = new double[s]; }
~Row(){ delete[]ro; }
double& operator[](int i) throw(out_of_range)
{if(i < 0 || i > size) throw out_of_range("Column index: Out of Range\n"); else
return ro[i];
} };
class Matrix
{ Row **mat; // Pointer to array of rows int lines, cols; // Number of rows and columns
public:
Matrix(int ro , int co )
{ lines = ro; cols = co;
mat = new Row*[lines];
for(int i=0; i < lines; i++) mat[i] = new Row(cols);
}
~Matrix()
{ for(int i=0; i < lines; i++)
delete mat[i];
delete[] mat;
} int getLines() const { return lines; } int getCols() const { return cols; }
Row& operator[](int i) throw(out_of_range)
{ if(i < 0 || i > cols) throw out_of_range("Row index: Out of Range\n"); else
return *mat[i];
} };
Class Matrix
Trang 7Now let’s develop an application that uses a class to represent dynamic matrices Matri-ces are used for computing vectors needed to move, rotate, or zoom images in graphics programming, for example
䊐 The Matrix Class
Memory is to be allocated dynamically to a matrix mat runtime Additionally, it should
be possible to use the index operator to access the elements of the matrix
Example: m[i][j] // Element in row i, column j
The class will therefore need a dynamic member to reference the matrix As you already know, a matrix is a single-dimensional array whose elements are single-dimensional arrays themselves
The class Row, which can be used to represent single-dimensional arrays of double
values, is defined opposite The index operator is overloaded for the Rowclass to allow
an exception of the out_of_rangetype to be thrown for invalid indices
The Matrixclass contains a dynamic member, mat, which can address an array of pointers to Rowobjects.matis thus a pointer to a pointer
䊐 Constructor, Destructor, and Subscript Operator
The constructor in the Matrixclass creates an array of linespointers to objects of the
Rowtype A loop is then used to allocate memory to the rows dynamically
In contrast, the destructor releases the memory occupied by the line arrays first, before releasing the space occupied by the pointer array mat
The subscript operator in the Matrixclass returns the line array ifor a given index
i When the following expression is evaluated
Example: m[2][3]
the first call is to the subscript operator of the Matrixclass, which returns a line array to index 2 Then the subscript operator of the Row class is called for the line array It returns a reference to the doublevalue at index 3
You will be enhancing the Matrixclass in the exercises to this chapter by overload-ing the copy constructor and the assignment, for example
Trang 8696 C H A P T E R 3 0 M O R E A B O U T P O I N T E R S
#include <iostream>
using namespace std;
char* color[] = {"WHITE", "PINK", "BLUE", "GREEN" };
int main() {
cout << *color[1] << " "
<< *color << " "
<< *(color[3] + 3) << " "
<< color[2] + 1 << " "
<< *( *(color + 1) + 3)
<< endl;
return 0;
}
Since the comparison function comparewill be called as a C function, it should
be declared and defined as extern "C" int compare( );
Refer to the Appendix “Binding C Functions.”
Listing for exercise 1
For exercise 3
The standard function qsort()
#include <cstdlib>
void qsort( void* array, size_t n, size_t size,
int (*compare)(const void*, const void*));
The function qsort(), ”quick sort,” sorts an array of nelements whose first element is pointed to by array.The size of each element is specified by size The comparison function pointed to by compareis used to sort the content
of the array in ascending order qsort()calls the function with two arguments that point to the elements being compared
You will normally need to define the comparison function yourself.The function must return an integer less than, equal to, or greater than zero if the first argument is less than, equal to, or greater than the second
Trang 9You can use the SelectionSort()function defined in Exercise 4 of Chapter 17 as an algorithm for sorting the intvalues in this exercise
Use the standard function qsort(), whose prototype is defined opposite, as quick sort algorithm for this exercise
Exercise 1
What does the program opposite output on screen?
Exercise 2
Write a function min()that computes and returns the minimum of two positive
numbers.The function expects a variable number of unsigned intvalues as arguments.The last argument must be the number 0
Exercise 3
Write a C++ program that compares the speed of the quick sort and selection sort algorithms
Sort two identical sequences of random numbers of the type intto test the sort algorithms Read the maximum number of random numbers from the keyboard and allocate the needed memory dynamically Display the time in seconds required for the sort operation on screen after each sort operation
Exercise 4
Write additional methods to complete the Matrixclass
■ Add a constversion of the subscript operator to the RowandMatrix
classes Use an inlineimplementation
■ Define a constructor for the Matrixclass.The constructor dynamically allocates a matrix with a given number of rows and columns, and initial-izes the matrix elements with a given value.Also write a copy construc-tor
■ Overload the assignment operator =and the compound assignment oper-ator+=
Addition is defined for two n⫻nmatrices,AandB, which have equal num-bers of rows and columns.The sum Cis a n⫻nmatrix whose elements are computed by adding elements as follows
C[i,j] = A[i,j] + B[i,j] for i, j = 0, , n-1
■ Test the Matrixwith a suitable mainfunction that calls all the methods Display the results of the calculations on screen
Trang 10698 C H A P T E R 3 0 M O R E A B O U T P O I N T E R S
Exercise 1
Screen output: P WHITE E LUE K
Exercise 2
// -// minivar.cpp
// Defines and tests the function min(), which // computes and returns the minimum of positive integers // The function expects a variable number of arguments // with unsigned int types
// The last argument must be 0!
//
-#include <stdarg.h>
unsigned int min( unsigned int first, ) {
unsigned int minarg, arg;
va_list argptr; // Pointer to optional arguments if( first == 0)
return 0;
va_start( argptr, first);
minarg = first;
while( (arg = va_arg(argptr, unsigned int) ) != 0) if( arg < minarg)
minarg = arg;
va_end (argptr);
return minarg;
}
// - A small function main() for
testing -#include <iostream>
using namespace std;
int main() {
cout << "\nThe minimum of : 34 47 19 22 58 "
<< "is: " << min(34, 47, 19, 22, 58, 0)
<< endl;
return 0;
}