Title: Complex%20Declarations:
1Complex Declarations
- We can declare arbitrarily complex data types
we are limited only by our imagination and our
ability to read and understand the resulting
declaration. For example - int (((fp))())
-
- fp is a pointer to an array of pointers to
functions, each of which takes no parameters and
returns a pointer to an array of integers.
2From Simple to Complex
Declaration
int p
int a10
int f(void)
int pa10
int g()
int (pa)10
int (fp)(char)
int (fa)()
int ((fp)())
int (((ff))())
int (f(int, char))()
Meaning
p is a pointer to an int
a is an array of ints
f is a function, no arg, returns an int
pa is an array of pointers to ints
g is a function, no arg, returns a ptr to an int
pa is a pointer to an array of ints
fp is a ptr to a function with an arg of char
fa is an array of function ptrs, no arg, return an int
fp is a ptr to a func returning a ptr to an int array
see previous slide
f is function taking an int and a char as argument, returning a ptr to a function, no arg, returns an int
3Constructing
- an array of
- pointers to
- functions taking no arguments and returning
- void
table ptr func(void)
table func(void)
(table)(void)
void (table)(void)
4Another Example
- a function taking three parameters and returning
- a pointer to
- a function taking one parameter and returning
- a pointer to chars
func1(3-arg) ptr func2(1-arg)
func1(3-arg) func2(1-arg)
(func1(3-arg))(1-arg)
char (func1(3-arg))(1-arg)
char (func1(int x, int y, char a))(double
(f)())
5Understanding
- Trickier than constructing a complex
declaration. - We start by finding its inner-most declarator.
- We write down its type, substitute an identifier
for this inner-most declarator, and repeat the
process until a single identifier remains. - The hard part is locating the inner-most
declarator.
6Example
thing is a pointer to an array of pointers
to functions returning u double (u)
thing is a pointer to x double ((x)())
thing is a pointer to an array of y double
((y)())
thing is a pointer to an array of pointers to
functions returning a pointer to an array of
doubles
thing is a pointer to an array of pointers to
z double (z())
7Example function that returns a pointer to a
function
- char g() return Smile
- char h() return Cry
- char (final(int mark))()
- if (mark gt 80) return g
- else return h
-
- int main()
- char r
- r (final(85))()
- printf(s\n, r)
- // or printf(s\n, (final(85))())
-
8Example int ((fp)())
- int a110 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
- int a210 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
- int (f()) return a1
- int (g()) return a2
- void exec(int ((fp))() )
- int i, (p)
- p (fp)()
- for (i 0 i lt 10 i )
- printf( d , (p)i)
- printf(\n)
-
- int main()
- exec(f)
- exec(g)
-
9Example int (((fp))())
- int a110 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
- int a210 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
- int (f()) return a1
- int (g()) return a2
- void exec(int n, int (((fp))()) )
- int i, (p)
- p ((fp)n)()
- for (i 0 i lt 10 i )
- printf( d , (p)i)
- printf(\n)
-
- int main()
- int ((ap2)()) f, g
- int (((fp))()) ap
- exec(0, fp)
- exec(1, fp)
-
int (p) p f() p (ap0)() p
((fp)0)()
10Type Specification
- When a declarator does not contain an
identifier, we have a type specification. - Type specifications are used in three places
function prototypes, casts and sizeof.
11Example
- Suppose we want to know how many bytes are
required by a pointer to a function taking an int
and returning a double, we need to use sizeof
operator. - // double (fp)(int) ? remove identifier fp to
form the type specifier - int sz sizeof(double ()(int))
12Another Example
- Suppose we have a generic function
- void max(void x, void y, int (cmp)(const
void , const void )) - and we want to use strcmp as the
- comparison function, we have to cast the
- function from
- int ()(char , char ) // strcmp type
specifier - to
- int ()(const void , const void ) // cmp
type specifier - such as
- char ms max(ABC, DEF, (int ()(const void
, const void )) strcmp)