Pointers to Functions Typedef Using Pointers to Functions
UNIX and C Programming (COMP1000)
Lecture 6: Pointers to Functions
Updated: 19th August, 2019
Department of Computing
Curtin University
Copyright © 2019, Curtin University
CRICOS Provide Code: 00301J
1/20
Pointers to Functions Typedef Using Pointers to Functions
Outline
Pointers to Functions
Typedef
Using Pointers to Functions
2/20
Pointers to Functions Typedef Using Pointers to Functions
Pointers to Functions
I Functions are stored in memory, just like variables.
I Pointers can point anywhere in memory, including to functions.
I There are special pointer types to represent this.
I These pointers can point to a function with specified
parameter/return types.
pointer
function() [machine code]
3/20
Pointers to Functions Typedef Using Pointers to Functions
Pointers to Functions — Why?
I Used to implement “callbacks”:
I You call one function, and give it a pointer to another function.
I The first function calls the second, in some fashion beyond
your control.
I The second function, which you write yourself, is the “callback”
function.
I Callbacks are used a lot in “Event-Driven Programming”. For
instance:
I Mouse clicks (and their consequences, such as button presses).
I Stopwatch timers.
I Network communication.
I With callbacks, you control what happens, but you let
something else decide when it should happen.
4/20
Pointers to Functions Typedef Using Pointers to Functions
Pointers to Functions – Declaration
I To declare a pointer to a function:
return-type (*variable-name)(parameters);
For example:
int (*ptr)(float x, int y);
The parameter names are optional (and just for show):
int (*ptr)(float, int); /* Same as above */
I Looks a bit like a function, but this is actually a variable.
I ptr holds the memory address of any function that:
I Takes a float and int parameters.
I Returns an int.
5/20
Pointers to Functions Typedef Using Pointers to Functions
Pointers to Functions – Assignment
I Consider this function:
int myFunction(float abc, int xyz) {
return ...;
}
I The address-of (&) operator works on functions (as well as
variables).
I So, &myFunction is the memory address of myFunction
(where its machine code is stored).
I We use this to initialise pointers to functions:
int (*ptr)(float, int);
ptr = &myFunction; /* ptr points to myFunction */
I Like all variables, we can combine declaration and initialisation:
int (*ptr)(float, int) = &myFunction;
6/20
Pointers to Functions Typedef Using Pointers to Functions
Pointers to Functions – Usage (1)
I Pointers to functions (like all pointers) are just values.
I They can be copied and assigned like other pointers.
I However, dereferencing a pointer to a function gives you a
function.
I Consider this:
ptr
int (*ptr)(float, int);
ptr = &func;
func() [machine code]
I The expression *ptr is now equivalent to func.
I And so (*ptr)(...) is now equivalent to func(...).
I i.e. we can take a pointer, and call the function it points to.
I And remember it could be any function (with the right
parameter and return types).
7/20
Pointers to Functions Typedef Using Pointers to Functions
Pointers to Functions – Usage (2)
To complete the example:
int myFunction(float abc, int xyz) {
return ...;
}
...
/* Declare ptr as a pointer to a function. */
int (*ptr)(float, int);
/* Make ptr point to myFunction. */
ptr = &myFunction;
/* Call the function it points to. */
int result = (*ptr)(7.0, 3);
8/20
Pointers to Functions Typedef Using Pointers to Functions
Pointers to Functions — Another Example
void printHello(void) {
printf("Hello world\n");
}
/* A function that takes a pointer to another
function, and calls it n times. */
void callNTimes(int n, void (*funcPointer)(void)) {
int i;
for(i = 0; i < n; i++) {
(*funcPointer)();
}
}
...
/* Prints "Hello world\n" 10 times. */
callNTimes(10, &printHello);
9/20
Pointers to Functions Typedef Using Pointers to Functions
Typedef
I The “typedef” keyword can be placed before any declaration.
I It converts the declaration into a “type declaration”.
I The name being declared instead becomes a new data type —
an alias.
I You can then use that name in place of the type it was
declared as.
I Normally used in header files.
Simplistic Example
typedef int INTEGER;
...
INTEGER num = 15;
10/20
Pointers to Functions Typedef Using Pointers to Functions
Typedef — Pointer Example
typedef void* MagicData;
MagicData getMagic(void);
void doMagic(MagicData magic);
I MagicData is equivalent to void*.
I The new name can serve as a form of documentation.
I void* could mean anything, but MagicData might indicate
something specific about the data.
I It can also be a primitive form of information hiding.
I Other code doesn’t need to know what MagicData really is.
11/20
Pointers to Functions Typedef Using Pointers to Functions
Typedef — Pointers to Functions
I typedef can simplify pointers to functions.
I You only need one convoluted declaration (in a header file):
typedef int (*MyType)(float, int);
I MyType is now shorthand for this convoluted pointer datatype:
int (*ptr)(float, int) = &myFunction;
MyType ptr = &myFunction; /* Equivalent */
I You can also return pointers to functions:
MyType function2(char a, double b) {
return &myFunction;
}
I Without typedef, the syntax for this would be very strange.
12/20
Pointers to Functions Typedef Using Pointers to Functions
Functions as Data Types
I With pointers to functions, you treat functions as data types!
I As a result, they can look bizarre.
I However, they follow the same rules as other declarations.
I (Those rules may be more subtle than you realised!)
Consider this ordinary function declaration:
int myFunction(float, int);
I Rule 1: all declarations consist of a name and a type 1 .
I Here, the type is “int. . . (float,int)” (not just “int”).
I “myFunction” has the type “int. . . (float,int)”.
I Part of the type goes on the left, and part goes on the right!
1
Except for parameters, where the name can be omitted in a forward
declaration.
13/20
Pointers to Functions Typedef Using Pointers to Functions
Pointers to Functions – Declarations (1)
I Say we want a pointer to “int. . . (float,int)”
(i.e. a pointer to a function with those parameters and return
type).
I Where does the * go?
I Rule 2: the * goes on the left of the name.
I Where does the name go?
I In the middle! (Since part of the type goes on the left, and
part on the right.)
14/20
Pointers to Functions Typedef Using Pointers to Functions
Pointers to Functions – Declarations (2)
Almost correct (but not quite)
int* myPointer(float,int);
I Everything is (basically) in the right place; the name is
surrounded by the type.
I However, this is a function returning a pointer, not a pointer
to a function.
I Why?
I “(. . . )” (the parameter list) has a higher precedence than “*”.
I Rule 3: If there’s “(. . . )” immediately to the right, you have
a function.
15/20
Pointers to Functions Typedef Using Pointers to Functions
Pointers to Functions – Declarations (3)
Correct
Rule 4: Brackets override operator precedence.
int (*myPointer)(float,int);
This declares a variable, pointing to a function that:
I imports a float and an int; and
I returns an int.
This declaration simply obeys the rules of C that you already know.
16/20
Pointers to Functions Typedef Using Pointers to Functions
Returning Pointers to Functions (1)
I Functions can return any data type, including pointers to other
functions.
I What would the declaration look like?
I Normally, a return type goes on the left. . .
I . . . but pointers to functions have separate parts on the left
and right.
I We also need two parameter lists!
I One for the function we’re declaring, and
I One for the pointer to a function it returns.
I Rule 5: Remember all the other rules.
17/20
Pointers to Functions Typedef Using Pointers to Functions
Returning Pointers to Functions (2)
1. First, write the function without a return type:
myFunction(char a, double b)
18/20
Pointers to Functions Typedef Using Pointers to Functions
Returning Pointers to Functions (2)
1. First, write the function without a return type:
myFunction(char a, double b)
2. It returns a pointer, so add a * on the left (Rule 2):
*myFunction(char a, double b)
18/20
Pointers to Functions Typedef Using Pointers to Functions
Returning Pointers to Functions (2)
1. First, write the function without a return type:
myFunction(char a, double b)
2. It returns a pointer, so add a * on the left (Rule 2):
*myFunction(char a, double b)
3. Add brackets to keep it that way (Rule 4):
(*myFunction(char a, double b))
18/20
Pointers to Functions Typedef Using Pointers to Functions
Returning Pointers to Functions (2)
1. First, write the function without a return type:
myFunction(char a, double b)
2. It returns a pointer, so add a * on the left (Rule 2):
*myFunction(char a, double b)
3. Add brackets to keep it that way (Rule 4):
(*myFunction(char a, double b))
4. Add the second parameter list, turning the returned pointer
into a pointer to a function (Rule 3):
(*myFunction(char a, double b))(float,int)
18/20
Pointers to Functions Typedef Using Pointers to Functions
Returning Pointers to Functions (2)
1. First, write the function without a return type:
myFunction(char a, double b)
2. It returns a pointer, so add a * on the left (Rule 2):
*myFunction(char a, double b)
3. Add brackets to keep it that way (Rule 4):
(*myFunction(char a, double b))
4. Add the second parameter list, turning the returned pointer
into a pointer to a function (Rule 3):
(*myFunction(char a, double b))(float,int)
5. Add the return type for the returned pointer to a function:
int (*myFunction(char a, double b))(float,int)
18/20
Pointers to Functions Typedef Using Pointers to Functions
Returning Pointers to Functions (3)
I Compare myFunction to myPointer (declared earlier):
int (*myPointer)(float,int)
int (*myFunction(char a, double b))(float,int);
(The type of myPointer and the return type of myFunction
are in red.)
I See the similarities and differences?
I myPointer is a pointer to a function.
I myFunction returns a pointer to a function.
I The brackets after the name make the difference between a
variable and a function (rule 3).
19/20
Pointers to Functions Typedef Using Pointers to Functions
Returning Pointers to Functions — Example
int simpleFunction(float x, int y) {
return 10;
}
int (*myFunction(char a, double b))(float,int) {
return &simpleFunction;
}
...
int (*myPointer)(float,int);
int result;
myPointer = myFunction(’A’, 2.5);
result = (*myPointer)(7.0, 3);
20/20