Reputation: 189
I'm trying to understand callbacks, and do get the idea, but do not understand why it is really needed.
Specifically, what added benefit does it provide over a normal function call? I'm looking at the accepted answer here : What is a "callback" in C and how are they implemented?
I have redone the same thing below, just without using function pointers. How is that different from this?
void populate_array(int *array, size_t arraySize)
{
for (size_t i=0; i<arraySize; i++)
array[i] = getNextRandomValue();
}
int getNextRandomValue(void)
{
return rand();
}
int main(void)
{
int myarray[10];
populate_array(myarray, 10);
...
}
Is it only beneficial if lower-layer software needs to call a function that was defined at a higher-layer?
Upvotes: 7
Views: 5485
Reputation: 8423
As said in the answer you linked to "there is no callback in c". There only is a method to pass pointers to function to a function.
Which is useful in general not only for lower-layer software that needs to call a function on a higher-level though this might be often how it is used.
Passing function pointers as parameters is an elegant way to write code. In your example if you want to have two variations on how to get the next random value you already see how it is much easier to pass the function as a parameter rather then trying to pass a parameter that then selects the next function to call using a switch.
Upvotes: 0
Reputation: 21585
To refine other answers here: Your function populate_array
has a bad name. It should be named populate_array_with_random_values
.
Upvotes: 0
Reputation: 33046
In your example, getNextRandomValue
must be known at compile time. This means that you cannot reuse the function with different definitions of getNextRandomValue
, neither let other users link to your code and specify their version of getNextRandomValue
. Note that this is not a callback, rather a "generic" function: think of getNextRandomValue
as a placeholder for a function.
Callbacks are a special use of "generic" functions: they are called upon completion of an asynchronous task, to notify the user of the operation results (or progress).
I don't think that function pointers only suit low-to-high-level communication. Function pointers, as said, allow you to build generic code in C. A quick example, qsort()
: order sorting needs a function that, given a
and b
, tells whether a>b
, a<b
or a==b
, so that a
and b
can be placed in the right order. Well, qsort
let you provide your own definition for order, thus offering a general, reusable piece of code.
Upvotes: 2
Reputation: 726479
This implementation is different in that the only way it knows to populate the array is hard-coded: getNextRandomValue
is the way it populates the array, and it is part of the library that provides the populate_array
functionality. Essentially, the two functions are baked together into a single whole (the fancy way of saying the same thing is to say that they are "tightly coupled").
With the original implementation I can do all of the things below without changing a line in the populate_array
:
int getNextRandomValue(void) {
return rand();
}
int getNextEvenValue(void) {
static int even = 2;
return (even += 2);
}
int getNextNegativeValue(void) {
static int neg = -1;
return neg--;
}
int getNextValueFromUser(void) {
int val;
scanf("%d", &val);
return val;
}
populate_array(myarray, 10, getNextRandomValue);
populate_array(myarray, 10, getNextEvenValue);
populate_array(myarray, 10, getNextNegativeValue);
populate_array(myarray, 10, getNextValueFromUser);
With your implementation I would have to write a separate populate_array
for each of these cases. If the way of populating an array that I need is not part of the library, I am on the hook for implementing the whole populate_array
, not only its value-producing generator function. This may not be that bad in this case, but in cases where callbacks really shine (threads, asynchronous communications) reimplementing the original without callbacks would be prohibitive.
Upvotes: 8