我不太明白这个目的。我已经搜索并阅读了不同来源的相同内容,但没有一个解释具体是什么以及它的目的是什么。
任何人都可以帮助我理解这个
答案 0 :(得分:3)
让我们来看看标准C库:
void qsort(void *BASE, size_t NMEMB, size_t SIZE,
int (*COMPAR)(const void *, const void *) );
qsort
的最后一个参数是指向比较函数的指针。 compare 函数用于比较数组中的两个元素(它定义了排序)。
如果qsort()
不使用函数指针,如果我们有不同的排序要求或新的类型/结构,我们将不得不一遍又一遍地写qsort()
我们想排序。
答案 1 :(得分:3)
采取以下措施:
int i = 10;
可以像这样定义相应的指针:
int* p = &i;
变量“p”与“i”非常相似,因为它们都是数字。但是,'p'的值是变量'i'的存储器地址,换句话说,它是存储值10的确切存储器地址。此外,'p'知道该存储器地址的值的类型。它知道它是一个“int”,因为它被定义为“int”+“star”。
同样,考虑一个函数:
int m(char* arg1, double arg2)
{
/* do something */
}
C提供了访问存储此函数的存储器地址的功能。函数不像一个值,例如它不能改变,所以当一个人说出一个函数的存储器地址时,这实际上意味着函数代码所在的存储器地址,例如,无论是花括号之间写的是什么。
然而,函数和变量之间存在相似性。他们都有一个类型。函数的类型包括:
C将具有相同返回类型和参数类型列表的所有函数视为“相同类型的函数”。类似于声明为“int i,j”的两个变量被认为是相同的类型,具有相同签名的两个函数也被认为是相同的类型。
描述函数类型的语法包括最小值:返回类型和每个参数的类型(按正确的顺序):
return-type (* <variable-name>)(Type-of-Param-1, Type-of-Param-2, ..., Type-of-Param-N)
实际上,为了在上面声明一个指向函数'm'的指针:
int (*p)(char*, double) = &m;
“int”是方法'm'的返回类型,圆括号的fir对和星号是语法的一部分,'p'是变量名,“char *”是第一个参数的类型,“double”是第二个参数的tyep。没有引用参数名称 - 因为参数的名称与函数的类型/签名无关。
请注意,与变量类似,方法的地址与变量的地址完全相同,即前缀为&符号。
指向函数的指针可以传递给simlar指向变量的指针,更重要的是,可以调用该特定内存地址的函数代码。例如,为了通过指针'p'调用函数'm',它将采用以下内容:
int result = p(NULL, 10.0);
int result = (*p) (NULL, 10.0); // alternative syntax
答案 2 :(得分:2)
典型的例子是一个排序函数,需要你将它“指向”一个可以比较两个元素的函数。您将此函数传递给比较函数的指针,以便在需要进行比较时调用函数。你实际上无法传递函数,但你可以传递一个指向函数的指针,该函数只是一个“指向”函数在内存中的位置的变量。排序函数可以使用此指针调用您的函数。通常,指针只是存储内存地址的变量。该内存地址是它“指向”的内容,它可以是该地址的任何内容 - 一个函数,一个整数,一系列以空字符结尾的字符变量。函数指针只是存储函数在内存中的内存地址的变量,因此该函数可以被其他一些代码调用。
希望解释有所帮助。
答案 3 :(得分:0)
这并不简单。
当您知道指针如何以及为什么使用常规变量时,请考虑使用这些指针,但这次使用函数。也就是说,你现在用函数的地址替换变量的地址,指针的所有功能,你现在可以通过使用指向它们的指针间接访问函数,而不是直接使用它们的名称。
来自http://www.cplusplus.com/doc/tutorial/pointers/
// my first pointer
#include <iostream>
using namespace std;
int main ()
{
int firstvalue, secondvalue;
int * mypointer;
mypointer = &firstvalue;
*mypointer = 10;
mypointer = &secondvalue;
*mypointer = 20;
cout << "firstvalue is " << firstvalue << endl;
cout << "secondvalue is " << secondvalue << endl;
return 0;
}
上面的输出是
firstvalue is 10
secondvalue is 20
现在来自http://www.newty.de/fpt/intro.html#what 我们有函数指针。
//------------------------------------------------------------------------------------
// 1.2 Introductory Example or How to Replace a Switch-Statement
// Task: Perform one of the four basic arithmetic operations specified by the
// characters '+', '-', '*' or '/'.
// The four arithmetic operations ... one of these functions is selected
// at runtime with a swicth or a function pointer
float Plus (float a, float b) { return a+b; }
float Minus (float a, float b) { return a-b; }
float Multiply(float a, float b) { return a*b; }
float Divide (float a, float b) { return a/b; }
// Solution with a switch-statement - <opCode> specifies which operation to execute
void Switch(float a, float b, char opCode)
{
float result;
// execute operation
switch(opCode)
{
case '+' : result = Plus (a, b); break;
case '-' : result = Minus (a, b); break;
case '*' : result = Multiply (a, b); break;
case '/' : result = Divide (a, b); break;
}
cout << "Switch: 2+5=" << result << endl; // display result
}
// Solution with a function pointer - <pt2Func> is a function pointer and points to
// a function which takes two floats and returns a float. The function pointer
// "specifies" which operation shall be executed.
void Switch_With_Function_Pointer(float a, float b, float (*pt2Func)(float, float))
{
float result = pt2Func(a, b); // call using function pointer
cout << "Switch replaced by function pointer: 2-5="; // display result
cout << result << endl;
}
// Execute example code
void Replace_A_Switch()
{
cout << endl << "Executing function 'Replace_A_Switch'" << endl;
Switch(2, 5, /* '+' specifies function 'Plus' to be executed */ '+');
Switch_With_Function_Pointer(2, 5, /* pointer to function 'Minus' */ &Minus);
}
正如您将从上面的调用中看到的那样,Minus()函数的地址被传递,然后传递给它以通过指针调用实际函数,在本例中为pt2Func(...)。 请注意,在函数指针的情况下,您也将处理函数签名。
float (*pt2Func)(float, float)
float Minus (float a, float b) { return a-b; }
如上所示,签名是相同的,因此您可以传入任何函数地址,并且调用将起作用。
我希望这会有所帮助。
答案 4 :(得分:0)
函数指针用于动态调用函数。例如,您可以将函数指针作为另一个函数的参数,并在某种意义上以这种方式提供其他功能。您还可以创建具有函数指针的结构,从而创建一些成员函数,例如类。如果你有一个适用于你的结构的函数,这可能是有用的,但它们在实际应该用它们做什么工作上可能有点不同。例如:
// Structures for our "objects"
typedef int funcPtr();
struct foo {
int a;
int b;
funcPtr* run;
}
struct bar {
int a;
int b;
funcPtr* run;
char* s;
}
// Functions that we will use as our "member functions"
int runOne() {
return 1;
}
int runTwo() {
return 2;
}
// Functions to create objects... kinda like new operators
struct foo* NewFoo(int aVal, int bVal) {
struct foo* this = (stuct foo*)malloc(sizeof(struct foo));
this->a = aVal;
this->b = bVal;
this->run = runOne;
return this;
}
struct bar* NewBar(int aVal, int bVal) {
struct bar* this = (stuct bar*)malloc(sizeof(struct bar));
this->a = aVal;
this->b = bVal;
this->run = runTwo;
return this;
}
// Create "objects"
struct foo* myFoo = NewFoo(10, 20);
struct bar* myBar = NewBar(30, 40);
// Run the run function on them (which actually runs different functions for each "object")
int result1 = myFoo->run();
int result2 = myBar->run();
result1 现在 1 , result2 2 。如果您的结构包含具有相似接口但具有不同行为的不同类型的“模块”,则可以使用此方法。