函数指针

函数的指针

  函数指针的声明方式

1
函数返回值类型(*指针变量名)(函数形参);

  函数指针的声明及调用,如下代码将会输出num1 + num2 = 3

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int main() {

// 声明函数指针
void(*pointer)(int,int);

// 取函数储存地址,赋值给函数指针
pointer = +

// 调用指针指向的函数
(*pointer)(1,2);

return 0;
}

void plus(int num1, int num2) {
printf("num1 + num2 = %d\n", num1+num2);
}

  函数指针可以被重新赋值,但是需要注意函数的形参,如下代码将会输出num1 - num2 = -1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
int main() {

// 声明函数指针
void(*pointer)(int,int);

// 取函数储存地址,赋值给函数指针
pointer = +

// 重新对函数指针赋值,
// sub函数与plus函数形参是一样的
pointer = ⊂

// 调用指针指向的函数
(*pointer)(1,2);

return 0;
}

void plus(int num1, int num2) {
printf("num1 + num2 = %d\n", num1+num2);
}

void sub(int num1, int num2) {
printf("num1 - num2 = %d\n", num1-num2);
}

  C语言规定,函数名本身就是指向函数的指针,因此不添加取地址符号&也可取函数指针,如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int main() {

// 取函数 test1 的地址值,赋值给函数指针
int(*pointer)(int) = test1;

// 调用 test1 函数
int result = (*pointer)(10);

// 输出返回值
printf("result = %d\n", result);

return 0;
}

int test1(int num) {
return num * num;
}

回调函数

  跟java里的回调方法不一样,所谓回调就是把函数指针作为实参传递给被调函数,在被调函数中调用形参中的函数指针

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
main() {

// 将函数指针作为可变参数传入 test
test(2, plus, sub);

return 0;
}

/**
* @param count 参数个数
* @param ... 可变参数
*/
void test(int count, ...) {
// 存储可变参数
va_list vaList;

// 初始化 va_list
va_start(vaList, count);

// 从参数列表中取两个函数指针
int(*plus_pointer)(int,int) = va_arg(vaList, int(*)(int,int));
int(*sub_pointer)(int,int) = va_arg(vaList, int(*)(int,int));

// 调用函数指针
int plus_result = (*plus_pointer)(1,2);
int sub_result = (*sub_pointer)(1,2);

// 清理 va_list
printf("plus_result = %d\n", plus_result);
printf("sub_result = %d\n", sub_result);

va_end(vaList);
}

int plus(int num1, int num2) {
return num1 + num2;
}

int sub(int num1, int num2) {
return num1 - num2;
}