Data Structures and Algorithms Functions as Data Types PLSD210
Quicksort - library implementation POSIX standard void qsort( void *base, size_t n, size_t size, int (*compar)( const void *, const void * ) ); base address of array n number of elements size size of an element compar comparison function
Quicksort - library implementation POSIX standard Comparison function C allows you to pass a function to another function! void qsort( void *base, size_t n, size_t size, int (*compar)( const void *, const void * ) ); base address of array n number of elements size size of an element compar comparison function
Functions as data types - declaration int (*compar)( const void *, const void * ); Parentheses around the * and the name Distinguish this as a pointer to a function Contrast with ... int *compar( const void *, const void * ); This is a function returning an int *
Functions as data types Declaration So this declares a pointer to a function named compar that takes two void * arguments and returns an int int (*compar)( const void *, const void * ); The function returns an int and has two arguments, both void *
Functions as data types Declaration The compare function passed to qsort returns -1 *arg1 < *arg2 0 *arg1 == *arg2 +1 *arg1 > *arg2 int (*compar)( const void *, const void * ); The function returns an int and has two arguments, both void * Interpret as defining order - not magnitude
Functions as data types Use Library functions that need a special purpose function Sorting needs a concept of order compar function provides it Ordering rule could be quite complex for a complex record eg names in a telephone directory Searching also needs an order Notes on Web and in C texts - omitted from printed copy
Functions as data types Generalising our collection class We used pointers to objects Enabling one collection class to store any type of object All C pointers are the same! but we had to assume external itemkey or itemcmp functions Restricting us to one collection per program! Add the ordering function to the attributes Ordering rule stored with each collection object As many collections as we like!
Generalised Collection Class Redefine the constructor Add an element to the attributes Collection ConsCollection( int max_items, int (*compar)(const void *,const void * ) ); struct t_collection { int max_items; int cnt; int (*compar)( const void *, const void * ); void *data; }; Assumes array - make appropriate changes for list, tree, etc.
Generalised Collection Class In the constructor code, treat the function just like any other data item: Collection ConsCollection( int max_items, int (*compar)(const void *,const void * ) ) { Collection c; c = malloc( sizeof( struct collection ) ); if ( c != NULL ) { c->max_items = max_items; c->compar = compar; …… } return c; compar is a pointer to a function - usually the address of the beginning of the function’s code Copy the pointer (it’s an address) just like any other data value!
Using a pointer to a function Use the attribute as the name of a function: void *FindInCollection( void *key ) { int k; for(k=0;k<c->cnt;k++) { if( *c->compar( key, c->data[k] ) == 0 ) return c->data[k]; } return NULL; … and supply it with arguments, just like any other function! c->compar is a pointer to a function - de-reference to access the function
Using a pointer to a function Use the attribute as the name of a function: void *FindInCollection( void *key ) { int k; for(k=0;k<c->cnt;k++) { if( *c->compar( key, c->data[k] ) == 0 ) return c->data[k]; } return NULL; … but the compiler will be kind and understand if you forget this asterisk! c->compar is a pointer to a function - de-reference to access the function
Functions as Data - Other uses Table-driven code eg menus Each entry String Action to be performed if the entry is selected struct menu { char *desc; int (*action)( void ); } file_menu[ ] = { { “Save”, save_function }, { “Save as”, save_as_function }, … }; Pointer to a function … which takes no arguments
Functions as Data - Other uses Table-driven code eg menus Each entry String Action to be performed if the entry is selected struct menu { char *desc; int (*action)( void ); } file_menu[ ] = { { “Save”, save_function }, { “Save as”, save_as_function }, … }; Functions which are called when the item is selected Strings which appear in the menu
Functions as Data - Other uses Using the table struct menu { char *desc; int (*action)( void ); } file_menu[ ] = { { “Save”, save_function }, { “Save as”, save_as_function }, … }; void file_menu_callback() { int k = item_selected( file_menu ); file_menu[k].action(); } Find which item was selected Call the action function