1 <!DOCTYPE HTML PUBLIC
"-//W3O//DTD W3 HTML 2.0//EN">
2 <!-- This collection of hypertext pages is Copyright 1995-7 by Steve Summit. -->
3 <!-- This material may be freely redistributed and used -->
4 <!-- but may not be republished or sold without permission. -->
7 <link rev=
"owner" href=
"mailto:scs@eskimo.com">
8 <link rev=
"made" href=
"mailto:scs@eskimo.com">
9 <title>24.1 Declaring, Assigning, and Using Function Pointers
</title>
10 <link href=
"sx10.html" rev=precedes
>
11 <link href=
"sx10b.html" rel=precedes
>
12 <link href=
"sx10.html" rev=subdocument
>
15 <H2>24.1 Declaring, Assigning, and Using Function Pointers
</H2>
17 <p>Just as for data pointers,
18 we can think of three steps involved in using function pointers.
20 we must declare a variable which can hold a pointer to a function,
21 and this ends up being a somewhat complex declaration.
22 A simple function pointer declaration looks like this:
26 This declares
<TT>pfi
</TT> as a
27 pointer to a function which will return an
<TT>int
</TT>.
28 As in other declarations,
29 the
<TT>*
</TT> indicates that a pointer is involved,
30 and the parentheses
<TT>()
</TT> indicate that a function is involved.
31 But what about the extra parentheses around
<TT>(*pfi)
</TT>?
32 They're needed because there are precedence relationships
33 in declarations just as there are in expressions,
34 and when the default precedence doesn't give you what you want,
35 you have to override it with explicit parentheses.
37 the
<TT>()
</TT> indicating functions
38 and the
<TT>[]
</TT> indicating arrays
39 ``bind'' more tightly than
40 the
<TT>*
</TT>'s indicating pointers.
41 Without the extra parentheses, the declaration above would look like
43 int *pfi(); /* WRONG, for pointer-to-function */
45 and this would declare a function returning a pointer to
<TT>int
</TT>.
46 With the explicit parentheses, however,
48 </TT>tells us that
<TT>pfi
</TT> is a pointer first,
49 and that what it's a pointer to is a function,
50 and what that function returns is an
<TT>int
</TT>.
51 </p><p>It's common to use typedefs
55 with complicated types such as function pointers.
59 typedef int (*funcptr)();
61 the identifier
<TT>funcptr
</TT> is now a synonym
62 for the type ``pointer to function returning int''.
63 This typedef would make
64 declaring pointers such as
<TT>pfi
</TT> considerably easier:
71 we mentioned that typedefs were a little bit like preprocessor
72 <TT>define
</TT> directives, but better.
75 there's no way we could define a preprocessor macro which would
76 expand to a correct function pointer declaration,
77 but the
<TT>funcptr
</TT> type we just defined using
<TT>typedef
</TT>
80 a function pointer can of course be set to point to some function.
81 If we declare some functions:
87 then we can set our pointer
<TT>pfi
</TT> to point to one of them:
91 or to one or another of them depending on some condition:
97 (Of course, we're not restricted to these two forms;
98 we can assign function pointers under any circumstances we wish.
99 The second example could be rendered more compactly
100 using the conditional operator:
101 <TT>pfi = condition ?
&f2 :
&f3
</TT> .)
102 </p><p>In these examples, we've used the
<TT>&</TT> operator
104 to generate a pointer.
105 However, when generating pointers to functions,
106 the
<TT>&</TT> is optional,
107 because when you mention the name of a function but are not calling it,
108 there's nothing else you could possibly be trying to do except
109 generate a pointer to it.
110 So, most programmers write
121 using the conditional operator,
122 <TT>pfi = condition ? f2 : f3
</TT> ).
123 </p><p>(The fact that a function pointer is generated automatically
124 when a function appears in an expression but is not being called
125 is very similar to, and in fact related to,
126 the fact that a pointer to the first element of an array
127 is generated automatically when an array appears in an expression.)
129 once we have a function pointer variable
130 which does point to a function,
131 we can call the function that it points to.
132 Broken down to a near-microscopic level,
134 is a three-step procedure.
136 we write the name of the function pointer variable:
140 This is a pointer to a function.
141 Then, we put the
<TT>*
</TT> operator in front,
142 to ``take the contents of the pointer'':
146 Now we have a function.
147 Finally, we append an argument list in parentheses,
148 along with an extra set of parentheses to get the precedence right,
149 and we have a function call:
153 The extra parentheses are needed here
154 for almost exactly the same reason
155 as they were in the declaration of
<TT>pfi
</TT>.
159 *pfi(arg1, arg2) /* WRONG, for pointer-to-function */
162 ``call the function
<TT>pfi
</TT>
163 (which had better return a pointer),
164 passing it the arguments
<TT>arg1
</TT> and
<TT>arg2
</TT>,
165 and take the contents of the pointer it returns.''
167 what we want to do is take the contents of
<TT>pfi
</TT>
168 (which is a pointer to a function)
170 call the pointed-to function,
171 passing it the arguments
<TT>arg1
</TT> and
<TT>arg2
</TT>.
172 Again, the explicit parentheses override the default precedence,
173 arranging that we apply the
<TT>*
</TT> operator to
<TT>pfi
</TT>
174 and
<em>then
</em> do the function call.
175 </p><p>Just to confuse things,
177 parts of the syntax are optional here as well.
178 There's nothing you can do with a function pointer
179 except assign it to another function pointer,
180 compare it to another function pointer,
181 or call the function that it points to.
187 based on the parenthesized argument list,
188 that you're trying to call a function,
189 so the compiler goes ahead and calls the pointed to function,
190 just as if you'd written
194 When calling the function pointed to by a function pointer,
195 the
<TT>*
</TT> operator
196 (and hence the extra set of parentheses)
198 I prefer to use the explicit
<TT>*
</TT>,
199 because that's the way I learned it
200 and it makes a bit more sense to me that way,
203 see code which leaves it
209 <a href=
"sx10.html" rev=precedes
>prev
</a>
210 <a href=
"sx10b.html" rel=precedes
>next
</a>
211 <a href=
"sx10.html" rev=subdocument
>up
</a>
212 <a href=
"top.html">top
</a>
215 This page by
<a href=
"http://www.eskimo.com/~scs/">Steve Summit
</a>
216 //
<a href=
"copyright.html">Copyright
</a> 1996-
1999
217 //
<a href=
"mailto:scs@eskimo.com">mail feedback
</a>