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 |