Function Pointers

A Dr. Taylor Tutorial

Function pointers are a lot like regular pointers. They differ in that they point to executable instructions instead of data. A function pointer should specify the signature of the function.

We can declare a function pointer by:

uint8_t (*min)(uint8_t, uint8_t);

We can assign a function pointer to point to an actual function by:

uint8_t minimum(uint8_t num1, uint8_t num2)
{
  return num1 < num2 ? num1 : num2;
}
 
min = &minimum;

Now that the function pointer has been assigned, we can use it to call minimum using either of the following ways:

uint8_t answer = min(3, 8);
uint8_t answer = (*min)(3, 8);

The second line more accurately describes the operation; however, the first method is also legal (and means the same thing).

If you ever needed to pass a function pointer, and you didn't know how to do it, the following example would probably get you on the right track:

/**
 * Determines the smaller of the two arguments
 * @param num1 first number
 * @param num2 second number
 * @return The smaller of the two arguments, or either one if they are equal
 */
uint8_t minimum(uint8_t num1, uint8_t num2);
  
/**
 * Applies the specified operation to elements in the passed array.
 * @param operation Operation to be performed on the data in the array
 * @param data Array of data to be processed
 * @param length Number of elements in the array
 * @return Result of applying the operation to all of the elements in the array
 */
uint16_t processArray(uint8_t (*operation)(uint8_t, uint8_t),
                      uint8_t *data, uint8_t length);
  
int main()
{
  uint8_t nums[] = {4, 3, 8, 7, 13};
  uint16_t result = processArray(&minimum, nums, 5);
}
  
uint16_t processArray(uint8_t *data, uint8_t length,
                      uint8_t (*operation)(uint8_t, uint8_t))
{
  uint16_t answer = data[0];
  uint8_t i=1;
  while(i<length)
  {
    answer = operation(answer, data[i]);
  }
  return answer;
}

Suppose I had a few other functions that accepted two uint8_t arguments and returned a uint8_t value. Say,

Then I could use the same processArray function to produce completely different results. Observer causually (because it's that easy):

/**
 * Determines the smaller of the two arguments
 * @param num1 first number
 * @param num2 second number
 * @return The smaller of the two arguments, or either one if they are equal
 */
uint8_t minimum(uint8_t num1, uint8_t num2);
  
/**
 * Determines the larger of the two arguments
 * @param num1 first number
 * @param num2 second number
 * @return The larger of the two arguments, or either one if they are equal
 */
uint8_t maximum(uint8_t num1, uint8_t num2);
  
/**
 * Determines the sum of the two arguments
 * @param num1 first number
 * @param num2 second number
 * @return The sum of the two arguments
 */
uint8_t add(uint8_t num1, uint8_t num2);
  
/**
 * Determines the product of the two arguments
 * @param num1 first number
 * @param num2 second number
 * @return The product of the two arguments
 */
uint8_t multiply(uint8_t num1, uint8_t num2);
  
/**
 * Applies the specified operation to elements in the passed array.
 * @param operation Operation to be performed on the data in the array
 * @param data Array of data to be processed
 * @param length Number of elements in the array
 * @return Result of applying the operation to all of the elements in the array
 */
uint16_t processArray(uint8_t (*operation)(uint8_t, uint8_t),
                      uint8_t *data, uint8_t length);
  
int main()
{
  uint8_t nums[] = {4, 3, 8, 7, 13};
  uint16_t min = processArray(&minimum, nums, 5);
  uint16_t max = processArray(&maximum, nums, 5);
  uint16_t sum = processArray(&add, nums, 5);
  uint16_t product = processArray(&multiply, nums, 5);
}
  
uint8_t maximum(uint8_t num1, uint8_t num2)
{
  return num1 > num2 ? num1 : num2;
}
  
uint8_t add(uint8_t num1, uint8_t num2)
{
  return num1 + num2;
}
  
uint8_t multiply(uint8_t num1, uint8_t num2)
{
  return num1 * num2;
}

Tutorials for Other Courses

Additional Links

Site Mirror

This is a mirror to be used when http://myweb.msoe.edu/taylor/, (EDU instead of US) is not available.