函数指针的使用可以带来以下好处:
#include <stdio.h>
// 四则运算函数
int add(int a, int b) {return a + b;}
int subtract(int a, int b) {return a - b;}
int multiply(int a, int b) {return a * b;}
int divide(int a, int b) {return a / b;}
/*FuncPtr:定义一个函数指针(先括号再*),它接受两个整数参数int,int并返回一个整数结果int*/
typedef int (*FuncPtr)(int, int);
/*METHOD1:回调函数arithMetic:使用函数指针FuncPtr operation作为参数.函数指针可以用来实现回调四则运算函数,即将一个函数作为参数传递给另一个函数,并在后者中调用前者。这种方式可以使代码更加灵活,可以根据需要动态地改变函数的行为。*/
int arithMetic(FuncPtr operation, int a, int b) {return operation(a, b);}
/*METHOD2:函数指针数组:函数指针可用来指向函数指针数组,即一个数组中的每个元素都是指针,存放数据是一个指向四则运算函数的地址。这样可方便实现函数的动态调用。*/
FuncPtr funcPtr[4] = {&add, &subtract, &multiply, ÷};
/*METHOD3:函数指针作为返回值:函数指针可以作为函数的返回值,这样可以实现更加灵活的程序设计。*/
FuncPtr getFuncPtr(char op) {
if (op == '+') {return &add;} //返回值为函数指针,指向四则运算函数
else if (op == '-') {return subtract;}
else {return NULL;}
}
int main() {
int a = 5;
int b = 3;
/*METHOD1*/
FuncPtr addFunc1 = add; //定义addFunc1为指针FuncPtr,在把add地址赋值addFunc1,即可实现调用加法函数
int sum1 = arithMetic(addFunc1, a, b);
printf("和: %d\n", sum1);
//FuncPtr subtractFunc = subtract; //使用函数指针调用减法函数
int difference = arithMetic(subtract, a, b);// *FuncPtr=FuncPtr1 operation=&subtract
printf("差: %d\n", difference);
/*METHOD2*/
int sum2 = funcPtr[0](a, b);
printf("method sum2:%d\n", sum2);
/*METHOD3*/
FuncPtr addFunc3 = getFuncPtr('+');//return &add,指向四则运算函数
int sum3 = addFunc3(a, b);
printf("method sum3:%d\n", sum3);
return 0;
}
动态内存分配:指针函数可以用来动态分配内存空间,并返回指向该空间的指针。这样可以在程序运行时根据需要动态地分配内存,避免浪费内存空间。
#include <stdio.h>
#include <stdlib.h>
//定义了一个名为 fillFunc 的函数指针类型,它接受一个整数参数int并返回一个整数结果int。
typedef int (*fillFunc)(int);
//getArray 函数为接受一个 fillFunc 类型的函数指针参数 fill,并使用该函数指针来填充数组。
int* getArray(fillFunc fill, int size)
{
int* arr = (int*)malloc(size * sizeof(int));
for (int i = 0; i < size; i++) {
arr[i] = fill(i + 1);
}
return arr;
}
int increment(int x) {return x;}
int square(int x) {return x * x;}
int main() {
//使用 increment 和 square 函数指针调用 getArray 函数,以创建两个不同的数组
int* arr1 = getArray(increment, 5);
for (int i = 0; i < 5; i++) {printf("%d ", arr1[i]);}
printf("\n");
free(arr1);
int* arr2 = getArray(square, 5);
for (int i = 0; i < 5; i++) {printf("%d ", arr2[i]);}
printf("\n");
free(arr2);
return 0;
}
在这个例子中,我们定义了一个指针函数getArray,它接受一个整型参数size,并返回一个指向整型数组的指针。在main函数中,我们调用getArray函数并将返回的指针赋值给arr变量。然后我们使用for循环遍历arr数组并打印每个元素的值。最后我们使用free函数释放arr指向的内存空间。可以看到,指针函数getArray成功地返回了一个指向整型数组的指针,并且我们可以通过该指针访问数组中的元素。由于指针函数可以动态地分配内存空间,因此我们可以根据需要动态地分配内存,避免浪费内存空间。
函数指针可以用来返回指向结构体的指针,这样可以方便地创建和操作结构体对象
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
int id;
char name[20];
int age;
} Person;
Person* createPerson(int id, const char* name, int age) {
Person* p = malloc(sizeof(Person));
if (p != NULL) {
p->id = id;
strcpy(p->name, name);
p->age = age;
}
return p;
}
void printPerson(Person* p) {
printf("ID: %d\n", p->id);
printf("Name: %s\n", p->name);
printf("Age: %d\n", p->age);
}
int main() {
Person* p1 = createPerson(1, "Alice", 20);
Person* p2 = createPerson(2, "Bob", 25);
if (p1 != NULL && p2 != NULL) {
printPerson(p1);
printPerson(p2);
free(p1);
free(p2);
}
return 0;
}
在这个例子中,我们定义了一个结构体Person,它包含三个成员变量id、name和age。然后我们定义了一个函数指针createPerson,它接受三个参数id、name和age,并返回一个指向Person结构体的指针。在createPerson函数中,我们使用malloc函数动态分配内存空间,并将参数赋值给结构体的成员变量。最后我们返回指向该结构体的指针。在main函数中,我们分别调用createPerson函数创建两个Person对象,并使用printPerson函数打印每个对象的成员变量。最后我们使用free函数释放每个对象所占用的内存空间。
可以看到,指针函数createPerson成功地返回了一个指向Person结构体的指针,并且我们可以通过该指针访问结构体的成员变量。由于指针函数可以动态地分配内存空间,因此我们可以方便地创建和操作结构体对象。