Homework 1: Function Pointer Array Study
1. Difference Between Pointer Function and Function Pointer
- Pointer function:
Now we already know how pointers work in C and C plus plus. For example:
int * ptrInteger;
Here we put a * mark between int and ptrInteger to create a pointer to an integer. In the same way, we can put a * mark in the declaration of function to create a pointer function:
int * foo()
If we write the * to let it stay close to int, we can see that the function name is foo, it takes no argument, and its return type is int*, which is a pointer to integer.
- Function pointer
There is also function pointer in C, which is a little difficult to understand. Because in C, operator () will take priority over operator *, so we need to use parents to higher the pointer’s priority. Then we can write it as:
void (*fptr)()
The definition of function pointer: wikipedia
A function pointer (or subroutine pointer or procedure pointer) is a type of pointer supported by third-generation programming languages (such as PL/I, COBOL, Fortran,[1] dBASE dBL, and C) and object-oriented programming languages (such as C++ and D).[2]
Instead of referring to data values, a function pointer points to executable code within memory. When dereferenced, a function pointer can be used to invoke the function it points to and pass its arguments just like a normal function call. Such an invocation is also known as an “indirect” call, because the function is being invoked indirectly through a variable instead of directly through a fixed name or address.
From its definition we can learn that it is actually a pointer (not a function), apart from other kinds of pointer, it doesn’t points to value, but some code. In the previous example, we create a function pointer that points to a function named fptr, which takes no argument and its return type is void. According to its definition we can notice that it can also points to a function that has a return type of a pointer.
There are two ways to assign the address of a function to a function pointer:
fptr = foo;
fptr = &foo;
They are actually the same, the address operator & is not required because a single function identifier represents its address on the label. There are two ways to call a function with a pointer:
x = (*fptr)();
x = fptr();
The second format looks the same as the function call. But we tend to use the first format because it explicitly states that the function is called by a pointer rather than a function name.
2. Function Pointer Array
In C programming language, we can store values in array as well as pointers in array. Also we can store function pointers in an array. The declaration is:
void (*foo[])()
If we understand what is function pointer, then it’s easy for user to understand function pointer array. Now I will give you an example to illustrate this function pointer array.
3. Description of Application Scenario
As we know there are many ways to sort a list of numbers, we take three of them to illustrate:
- Select Sort
void SelectSort(int A[], int n){
int small;
for (int i=0; i<n-1; i++ ){
//i is the position of first element in sub-sequence to be sorted
small=i;
for (int j=i+1; j<n; j++) //traverse the sub-sequence to be sorted
if (A[j]<A[small])
small=j; //keep minimum value
int temp = A[small];
A[small] = A[i];
A[i] = temp;
}//endfor
}
- Direct Insertion Sort
void InsertSort(int A[], int n) {
//i is the starting subscript of unordered sub-sequence
for (int i = 1; i < n; i++) {
int j = i;
int temp = A[i];
//until temp greater than current element or j out of bounds
while(j > 0 && temp < A[j-1]) {
A[j] = A[j-1]; //move the element
j--;
}
A[j] = temp;
}
}
- Bubble Sort
void BubbleSort(int A[], int n){ //n is the number of elements
int i,j,last;
i=n-1;
while ( i>0 ) {
last=0;
for (j=0; j<i; j++)
if ( A[j+1]<A[j] ) { //if the first element is greater, swap them
int temp = A[j];
A[j] = A[j+1];
A[j+1] = temp;
last=j;
}//last is the index of the last element in unsorted sub-sequence
i=last;
}//endwhile
}
We can see that all three of sorting method requires an int array and the number of elements as an input. So here we can declare a function pointer array which is used to call these functions, we just name it sort:
void (*sort[])() = {SelectSort, InsertSort, BubbleSort}; //declaration of function pointer array
We can just call it directly:
void printout(int A[], int n); //print out an array
int main(int argc, char const *argv[])
{
//declaration of three unsorted arrays
int A[] = {1, 3, 2, 8, 7};
int B[] = {20, 5, 13, 79};
int C[] = {9, 456, 1, 3, 8, 10, 111};
//get the length of each array
int length_A = sizeof(A)/sizeof(A[0]);
int length_B = sizeof(B)/sizeof(B[0]);
int length_C = sizeof(C)/sizeof(C[0]);
//testing for SelectSort
sort[0](A, length_A);
printout(A, length_A);
//testing for InsertSort
sort[1](B, length_B);
printout(B, length_B);
//testing for BubbleSort
sort[2](C, length_C);
printout(C, length_C);
return 0;
}
void printout(int A[], int n) {
printf("%s\n", "Sorting result: ");
for (int i = 0; i < n; i++) {
if (i == n-1) {
printf("%d\n", A[i]);
}else{
printf("%d, ", A[i]);
}
}
}
Then the output is :
In the example above we use function pointer array to store three sorting function: SelectSort, InsertSort and BubbleSort. Then we can use the function pointer array to call it directly.
There are two parameters in void (*sort[])(int A[]. int n), here A[] is the array of integers that will be sorted, and n are the number of element to be sorted. sort[0] will call Select Sort, sort[1] will call Insert Sort, sort[2] will call Bubble Sort.
4. Advantages and Limitations
- advantages
This function pointer can save space and time if used to implement some functions that have similar usage, takes the same type of parameters and have the same type of return. In other word, it can achieve the similar method of implementing an interface in Java Programming language. It effectively reduce coupling of your code.
- limitations
Although its usage is like interface in Java, it is different from interface. Firstly it is actually pointers, which manipulate memory of your program, which means it is difficult to use and if wrongly used, lots of problems will occur. Secondly, it cannot achieve all the method of interface, it just achieve part of function of that in Java.