what is the magic on the finding
function below?
1) what is this inner mechanism that allows match
to be used without being declared previously?
2) In main
, shouldn't the finding
call pass the array ADS
along with sports_no_trucks
?
Thanks in advance!
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int NUM_ADS = 2;
char *ADS[] = {
"Luis: SLM ND likes sports, theater, art",
"Mike: DWM DS likes trucks, sports"
};
void finding(int (*match) (char *))
{
int i;
puts("Search results:");
puts("------------------------------------");
for (i = 0; i < NUM_ADS; i++)
{
if (match(ADS[i]))
{
printf("%s\n", ADS[i]);
}
}
puts("------------------------------------");
}
int sports_no_trucks(char *s)
{
return strstr(s, "sports") && !strstr(s, "trucks");
}
int main()
{
finding(sports_no_trucks);
return 0;
}
In this function declaration
void finding(int (*match) (char *));
there is declared one parameter with the name match
that has the type of pointer to function of the type int( char * )
. That is the parameter match
itself has the type int ( * )( char * )
.
In the call of the function finding
finding(sports_no_trucks);
there is passed as an argument function designator sports_no_trucks
that corresponds to the following definition of the function
int sports_no_trucks(char *s)
{
return strstr(s, "sports") && !strstr(s, "trucks");
}
So the parameter match
of the function finding
gets the value of the pointer to the function sports_no_trucks
because function designators used in expressions are converted to pointers to functions.
You can imagine the definition of the function finding
and its call the following way
finding(sports_no_trucks);
//...
void finding( /* int (*match) (char *) */ )
{
int ( *match )( char * ) = sports_no_trucks;
//...
}
To make it more clear you can introduce a typedef name like
typedef int FN( char * );
In this case the declaration of the function finding will look like
void finding( FN *match );
where FN
is an alias for the function type int( char * )
.
2) In main , shouldn't the finding call pass the array ADS along with sports_no_trucks?
The array declared as a global variable
int NUM_ADS = 2;
char *ADS[] = {
"Luis: SLM ND likes sports, theater, art",
"Mike: DWM DS likes trucks, sports"
};
And the function finding
has access to it because it is visible in the file scope of the program
for (i = 0; i < NUM_ADS; i++)
{
if (match(ADS[i]))
{
printf("%s\n", ADS[i]);
}
}
But you are right. It is a bad style of programming when functions depend on global variables. In this case you are unable to call the function for another array. So this function is not a general function. It is very specific and can deal with only one array.
There was no need to declare the array as global and define the function that depends on the global array.
In this case the function declaration can look like
void finding( char * s[], size_t n, int (*match) (char *));
and the function could be called for the array ADS like
finding( ADS, NUM_ADS, sports_no_trucks );
But it could be called for any other array the same way
finding( AnotherArray, ItsSize, sports_no_trucks );