关于 C 中的函数指针
About function pointers in C
下面的 finding
函数有什么神奇之处?
1) 允许使用 match
而无需事先声明的内部机制是什么?
2) 在 main
中, finding
调用不应该将数组 ADS
与 sports_no_trucks
一起传递吗?
提前致谢!
#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;
}
int name(char *s)
将 name
声明为一个接受 char *s
参数并返回 int
.
的函数
int (*name)(char *s)
将 name
声明为指向该类型函数的指针。
在void finding(int (*match) (char *))
中,我们看到参数match
声明如上。
1) what is this inner mechanism that allows match
to be used without being declared previously?
match
在使用前声明;在 void finding(int (*match) (char *))
中,它被声明为函数 finding
的参数,具有上述类型。
2) In main
, shouldn't the finding
call pass the array ADS
along with sports_no_trucks
?
不必如此,因为 ADS
是在任何函数外部声明的,并且在定义 finding
之前,所以 ADS
对 finding
内部的代码可见。 (如果可以避免的话,像这样使用外部标识符通常被认为是糟糕的设计。)
在此函数声明中
void finding(int (*match) (char *));
声明了一个名称为 match
的参数,其类型为指向函数的指针类型 int( char * )
。那就是参数 match
本身的类型是 int ( * )( char * )
.
在函数的调用中finding
finding(sports_no_trucks);
作为参数传递的函数指示符 sports_no_trucks
对应于函数的以下定义
int sports_no_trucks(char *s)
{
return strstr(s, "sports") && !strstr(s, "trucks");
}
所以函数finding
的参数match
得到函数指针的值sports_no_trucks
因为表达式中使用的函数指示符被转换为函数指针
你可以想象函数finding
的定义及其调用方式
finding(sports_no_trucks);
//...
void finding( /* int (*match) (char *) */ )
{
int ( *match )( char * ) = sports_no_trucks;
//...
}
为了更清楚,您可以引入一个 typedef 名称,例如
typedef int FN( char * );
在这种情况下,函数查找的声明将如下所示
void finding( FN *match );
其中 FN
是函数类型 int( char * )
.
的别名
2) In main , shouldn't the finding call pass the array ADS along with
sports_no_trucks?
声明为全局变量的数组
int NUM_ADS = 2;
char *ADS[] = {
"Luis: SLM ND likes sports, theater, art",
"Mike: DWM DS likes trucks, sports"
};
并且函数 finding
可以访问它,因为它在程序的文件范围内可见
for (i = 0; i < NUM_ADS; i++)
{
if (match(ADS[i]))
{
printf("%s\n", ADS[i]);
}
}
但你是对的。当函数依赖于全局变量时,这是一种糟糕的编程风格。在这种情况下,您无法为另一个数组调用该函数。所以这个函数不是一般的函数。它非常具体,只能处理一个数组。
无需将数组声明为全局数组并定义依赖于全局数组的函数。
在这种情况下,函数声明可以如下所示
void finding( char * s[], size_t n, int (*match) (char *));
并且可以为数组 ADS 调用该函数,例如
finding( ADS, NUM_ADS, sports_no_trucks );
但是可以用同样的方式为任何其他数组调用它
finding( AnotherArray, ItsSize, sports_no_trucks );
也许这样写会更容易理解
typedef int functype(char *);
void finding(functype *func)
{
/* ... */
}
functype
是返回 int
并采用 char *
参数的函数类型
functype *func
是指向该类型的指针。现在它看起来和任何其他指针一样
ADS是一个全局变量,可以在程序的任何地方访问。
下面的 finding
函数有什么神奇之处?
1) 允许使用 match
而无需事先声明的内部机制是什么?
2) 在 main
中, finding
调用不应该将数组 ADS
与 sports_no_trucks
一起传递吗?
提前致谢!
#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;
}
int name(char *s)
将 name
声明为一个接受 char *s
参数并返回 int
.
int (*name)(char *s)
将 name
声明为指向该类型函数的指针。
在void finding(int (*match) (char *))
中,我们看到参数match
声明如上。
1) what is this inner mechanism that allows
match
to be used without being declared previously?
match
在使用前声明;在 void finding(int (*match) (char *))
中,它被声明为函数 finding
的参数,具有上述类型。
2) In
main
, shouldn't thefinding
call pass the arrayADS
along withsports_no_trucks
?
不必如此,因为 ADS
是在任何函数外部声明的,并且在定义 finding
之前,所以 ADS
对 finding
内部的代码可见。 (如果可以避免的话,像这样使用外部标识符通常被认为是糟糕的设计。)
在此函数声明中
void finding(int (*match) (char *));
声明了一个名称为 match
的参数,其类型为指向函数的指针类型 int( char * )
。那就是参数 match
本身的类型是 int ( * )( char * )
.
在函数的调用中finding
finding(sports_no_trucks);
作为参数传递的函数指示符 sports_no_trucks
对应于函数的以下定义
int sports_no_trucks(char *s)
{
return strstr(s, "sports") && !strstr(s, "trucks");
}
所以函数finding
的参数match
得到函数指针的值sports_no_trucks
因为表达式中使用的函数指示符被转换为函数指针
你可以想象函数finding
的定义及其调用方式
finding(sports_no_trucks);
//...
void finding( /* int (*match) (char *) */ )
{
int ( *match )( char * ) = sports_no_trucks;
//...
}
为了更清楚,您可以引入一个 typedef 名称,例如
typedef int FN( char * );
在这种情况下,函数查找的声明将如下所示
void finding( FN *match );
其中 FN
是函数类型 int( char * )
.
2) In main , shouldn't the finding call pass the array ADS along with sports_no_trucks?
声明为全局变量的数组
int NUM_ADS = 2;
char *ADS[] = {
"Luis: SLM ND likes sports, theater, art",
"Mike: DWM DS likes trucks, sports"
};
并且函数 finding
可以访问它,因为它在程序的文件范围内可见
for (i = 0; i < NUM_ADS; i++)
{
if (match(ADS[i]))
{
printf("%s\n", ADS[i]);
}
}
但你是对的。当函数依赖于全局变量时,这是一种糟糕的编程风格。在这种情况下,您无法为另一个数组调用该函数。所以这个函数不是一般的函数。它非常具体,只能处理一个数组。
无需将数组声明为全局数组并定义依赖于全局数组的函数。
在这种情况下,函数声明可以如下所示
void finding( char * s[], size_t n, int (*match) (char *));
并且可以为数组 ADS 调用该函数,例如
finding( ADS, NUM_ADS, sports_no_trucks );
但是可以用同样的方式为任何其他数组调用它
finding( AnotherArray, ItsSize, sports_no_trucks );
也许这样写会更容易理解
typedef int functype(char *);
void finding(functype *func)
{
/* ... */
}
functype
是返回 int
并采用 char *
functype *func
是指向该类型的指针。现在它看起来和任何其他指针一样
ADS是一个全局变量,可以在程序的任何地方访问。