*foo() 2-0-1- foo is function returnong pointer //foo*() foo is pointer to a function ILLEGAL (*foo)() use grouping parenthesis double (*(*foo)[5])( int ); 3 exceptions: // foo()() - illegal // foo()[] - illegal // foo[]() - illegal foo[4][4] - legal But int (*foo(int i)) [5] 2------1-- -4----------------3- (*foo())() - illegal (*foo[])() - illegal int* foo(int i) 3--2-------1-- <<<<<<<< foo >>>>>>>> int *(*f6)[3]; f6 is pointer array of 3 pointers to int 1-- -4--3------2- usage: int j = *(*f6)[2]; int *(*f12[3])[4] 2----1- -5--4----------3-- BITMAP *(*((*foo)[5]))(const char *, int); 1--- -------2- 3---------- --6----5-----------------4--------------- foo is an array of 5 of pointer to arrays of 7 of ints foo [5] * [7] int int (*foo[5] ) [7]; 2----1- 4---------------3 foo is a function that takes a foo ( (pointer to a function that takes int and return int) and rturns a pointer to an array of 5 doubles ) * [5] double double (*foo( ??? )) [5]; ---------- bar pointer to a function that takes int and return int int (* bar) (int) double (*foo( int (* bar) (int) )) [5]; int foo( int i ); // prototype int foo( int ); // prototype double (*foo( int (* bar) (int) )) [5]; double (*foo( int (*) (int) )) [5]; ------------ (*)() foo is a function that takes (a pointer to a function int and returns int and ) returns a pointer to a function int and returns int int (* foo ( ???? ) ) ( int ) -2--------1---- 5---------------------3--4--- bar a pointer to a function int and returns int int (*bar) (int) int (* update_strategy ( int (*) (int)) ) ( int ); // a pointer to a function int and returns int int i; typedef int MyInt; int (*p)(int); typedef int (*PFI_I)(int); PFI_I foo( PFI_I ); a2 a_ _a //2a int _; int __; int ___; int l; int o; int O; int _1_; const int ci; int const ci; // sounds better typedef Node * Handle; // opaque pointer insert( Handle * pHead ); insert( Node * * pHead ); // compiled void print ( Handle const head ); // const correctness ?? void print ( Node * const head ) { // head is a const ptr to modifiable Node while ( head ) { head -> data = 6; //head = head -> next; } } void print ( const Handle head ); // const correctness ?? void print ( const Node * head ) { // head is a ptr to a Node that is cont ???? NOOOOOOOOOOO !!!!!!!! // nothing changed while ( head ) { head -> data = 6; //head = head -> next; } } // compiler ALAWYS fixes const to be to the right of type you type const int i; compiler fixes int const i; // same as before double const * pd; void print ( Node const * head ) { // cannot be achieved by the previous typedef while ( head ) { //head -> data = 6; head = head -> next; } typedef Node const * ConstHandle; // opaque pointer void print ( ConstHandle head ) f = &f *f = *&f *f =f // in math: fixed point **f = *f = f ***********f = f so foo( i ) same: (**************************foo)( i ) // f = &&f; next lecture int foo( int i ) { return i+i; } int (*p)(int); p = foo; // syntactic sugar instead &foo; SLOPPY SYNTAX p = &foo; // GOOD (*p)(10); // GOOD p(10); // lets allow this C++: is sloppy with C-style function - calling through a pointer is NOT sloppy with C++-only function: methods (obj.*pm)(10); (p_processor->*p_method)(...);