You've learned how to write basic functions, but there is a great deal more to the story. Functions can handle pointers in a variety of ways, the simplest of which is in the parameters. The two ways of handling parameters are codified into two forms: passing by reference and value. Passing by reference you already know how to do; the compiler simply creates a copy of the value you are passing and uses it, leaving the original untouched. The second method, passing by value, is essentially passing the address of the value being passed using pointers. This means that rather than creating a normal variable and storing the value into it, the compiler creates a pointer which stores the address of the original value passed. This has the effect of changing the original value if any modifications are made to it within the function. There is nothing new here, by the way; just an application that you probably wouldn't consider.
void myFunction(int *val);
int main()
{
int var = 3;
myFunction(&var);
return 0;
}
void myFunction(int *val)
{
*val *= 2;
}
At the top is the prototype, which you're already familiar with other than the pointer declaration as a parameter. Next is a simple main() function which declares and initializes var and then passes its location in memory to myFunction (remember, we declared a pointer as the parameter so we have to pass var's address using the ampersand!) Finally, we have myFunction which simply doubles the value it receives. Remember do dereference the pointer so it uses the value it is pointing to rather than the address it is storing. After myFunction executes, var will be 6, since its location in memory was given to and used by myFunction.
Now onto the principles that will make your head spin. It is also possible to create pointers to functions, which in turn allows you to pass functions as arguments to other functions or -- what the heck -- throw like functions in your program into an array. While there are only two applications for this that I can think of (eliminating a small amount of code and looking smart), it is still very interesting to know how to do. First off, your function pointer must contain identical parameters & return types to the function it is going to point to. After that, it is simply a case of assigning the function to the pointer and dereferencing it to use it.
int nTimesTwo(int n);
int main()
{
int (*pt)(int n);
pt = &nTimesTwo;
cout << (*pt)(3) << endl;
return 0;
}
int nTimesTwo(int n)
{
return n * 2;
}
First, we prototyped and created our nTimesTwo function. Then, we go into the main function and create the pointer. Notice how the return type (int) and the parameters (int n) are identical to function nTimesTwo; this is a requirement. Next, notice how *pt is in parentheses. This is also a requirement; without it, you'll simply be declaring a function that returns a pointer (which you can do). Next, we assign the pointer the memory address of the function. Finally, we use the pointer like a normal function, except we have to dereference it (again, using parentheses).
Passing a function as an argument is a largely similar process. Simply place the pointer declaration as a parameter in a function to create it, and then pass the address of an identical function to use it. Here's an example, which assumes nTimesTwo exists.
int nTimesXTimesN(int n,int (*pt)(int x));
int main()
{
int var = 3;
cout << nTimesXTimesN(var,&nTimesTwo) << endl;
return 0;
}
int nTimesXTimesN(int n, (*pt)(int x))
{
return n * (*pt)(n);
}
As you can see, that whole pointer function declaration has been placed into the function header as an argument. In the main() function, you'll notice that I simply pass the address of nTimesTwo in that pointer's slot in the argument list. Finally, you'll see it used in the bottom function. You may also have noticed a glaring limitation to this strategy: functions sent as arguments to another function cannot have any of their own arguments sent with them; those have to come from somewhere else, such as in another argument as I did above.
Setting up an array of functions is easy; in fact, it pretty much forces you to use bracket notation. All you must do is declare your pointer as usual, except now you have to place brackets containing the number of elements you want your array to have. Then, simply assign each element a different function. From there, you can simply call any element as you would a normal function pointer. I'll just assume that the proper prerequisites exist for the function assignments in the following example.
int (*pt[4])(int n);
(*pt[0]) = &nTimes2;
(*pt[1]) = &nTimes3;
(*pt[2]) = &nTimes4;
(*pt[3]) = &nTimes5;
for(int i = 0; i < 4; i++)
{
var = (*pt[i])(var);
}
As you can see, the brackets go right next to the pointer name at all times. Other than that, there is no difference in usage.