| Data Structures and Algorithms |
| Functions as Data Types |
int ItemCmp( void *a, void *b );
which returns -1, 0 or +1 depending on whether a is less than, equal to or greater than b. (Note that we're allowing a very general notion of 'less than': the ItemCmp can order items according to any rule which might be appropriate to these items.)
So we add to our collection structure, a comparison function:
struct t_collection {
int item_cnt;
int (*ItemCmp)( void *, void * );
....
};
ItemCmp is a pointer to a function which has the prototype:
int ItemCmp( void *, void * );
The parentheses are necessary to distinguish this declaration from the
function prototype and an invocation of the function!
The ConsCollection function now becomes:
collection ConsCollection( int max_items,
int (*ItemCmp)( void *, void * ) );
A use of the collection now looks like:
#include "widget.h" /* import the ADT for widgets */
int WidgetComp( widget, widget );
collection LotsOfWidgets;
LotsOfWidgets = ConsCollection( large_no, WidgetComp );
In the body of the ADT, the ItemCmp function is used by de-referencing the pointer to the function and using it normally: in FindInCollection, we might have:
int FindInCollection( collection c, void *a )
{
.....
if ( (*(c->ItemCmp))( c->items[i], a ) == 0 )
{
/* Found match ... */
....
}
In the example above, an excessive number of parentheses has been used, because I simply don't want to bother to look up the precedence rules: why risk making a silly mistake, when a few extra parentheses will ensure that the compiler treats the code as you intended?
However, C permits a 'shortcut' - which doesn't require de-referencing the pointer to the function: in the source code examples, an ItemCmp function has been added to a tree collection.
Key terms |
| Continue on to ADTs in Ada | Back to the Table of Contents |