c语言参数指针,C语言函数指针

66b52468c121889b900d4956032f1009.png

8种机械键盘轴体对比

本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?

指针是C语言的一大特色,也是其学习过程中的一大难点,在一般的编程中,我们见得最多的就是常见数据类型的指针变量,包括基本数据类型和复合数据类型,而针对于函数指针的编程则显得少之又少,不过,少见并不代表其不重要,利用好它将有助于我们在复杂的项目中大大提高代码的复用率,下面我们来一起学习函数指针的最基本使用方法。

Hello World 与函数指针

和学习其他编程语言一样,我们将从最简单的 Hello World 程序来学习函数指针的使用方法。在 C 语言中,我们通常会使用一下的方式来输出一个 Hello World :1

2

3

4

5

6

7

8

9

10

11void (){

printf("Hello World!n");

}

int main(){

sayHello();

return 0;

}

这里我们创建了一个返回值为 void 类型、参数为空的函数 sayHello,使用C语言标准输出函数 printf 打印出 Hello World!,在主函数中,我们直接通过函数名调用该函数打印出 Hello World!。下面,我们将创建一个最简单的函数指针来实现同样的功能:1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16void (){

printf("Hello World!n");

}

int main(){

sayHello();

void (* ptr)() = sayHello;

ptr();

(*ptr)();

return 0;

}

我们先来看一看程序执行结果:1

2

3

4

5lihuideMacBook-Pro:Learn lihui$ gcc -o hello hello.c

lihuideMacBook-Pro:Learn lihui$ ./hello

Hello World!

Hello World!

Hello World!

可以看到,和通过函数名调用函数一样,通过函数指针调用函数的两种方式同样打印出了 Hello World! ,我们来分析一下这个过程是如何实现的:首先,我们通过 void (* ptr)() = sayHello 的方式定义了一个函数指针,并将函数 sayHello 的地址赋给它,这里,我们需要注意的是,void 代表函数指针所指向函数的返回值类型,函数名代表的是函数地址,这和数组名代表数组地址是一样的;

(* ptr) 表示一个指向函数的指针,一定要用括号括起来,否则就变成了 void * ptr(),这表示一个返回值类型为 void 的函数,而非函数指针;

(* ptr) 后的 () 则是函数指针所指向函数的参数列表,这里 sayHello 函数的参数列表为空;

在定义完函数指针后,我们通过两种方式来调用函数指针所指向的函数,分别是: ptr() 和 (* ptr)(),这两种调用方式的结果是一样的;

由以上分析可以,通过 void (* ptr)(),我们实际上定义了一个指向参数列表为空,返回值类型为 void 的函数指针 ptr。通过 ptr() 或者是 (* ptr)(),我们可以调用函数指针 ptr 所指向的函数。

带参数的函数指针

我们不妨改进一下上面的 Hello World 程序,使其可以动态的输出调用者的名字:1

2

3

4

5

6

7

8

9

10

11void (char *author){

printf("Hello World! By %s.n", author);

}

int main(){

sayHello("Hui Li");

return 0;

}

同样的,我们将上面带参数的 Hello World 程序改为通过函数指针的方式执行:1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16void (char *author){

printf("Hello World! By %s.n", author);

}

int main(){

sayHello("Hui Li");

void (* ptr)(char *) = sayHello;

ptr("Hui Li");

(*ptr)("Hui Li");

return 0;

}

看一下程序执行结果:1

2

3

4

5lihuideMacBook-Pro:Learn lihui$ gcc -o hello hello.c

lihuideMacBook-Pro:Learn lihui$ ./hello

Hello World! By Hui Li.

Hello World! By Hui Li.

Hello World! By Hui Li.

和预期一样,函数依然正确执行。和不带参数列表的函数指针不同,指向带参函数的指针在定义时必须定义与所指函数参数列表一致的参数列表,这样才能保证我们可以通过函数指针来正确调用其所指的函数。

带参数列表和返回值类型的函数指针

现在,我们来写一个既带参数,又有返回值的程序:1

2

3

4

5

6

7

8

9

10

11

12int add(int a, int b){

return a + b;

}

int main(){

int sum = add(3, 5);

printf("%d + %d = %dn", 3, 5, sum);

return 0;

}

我们将其修改为函数指针来执行:1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20#include

int add(int a, int b){

return a + b;

}

int main(){

int sum = add(3, 5);

printf("%d + %d = %dn", 3, 5, sum);

int (* ptr)(int, int) = add;

int sum_1 = ptr(3, 5);

printf("%d + %d = %dn", 3, 5, sum_1);

int sum_2 = (*ptr)(3, 5);

printf("%d + %d = %dn", 3, 5, sum_2);

return 0;

}

看一下执行结果:1

2

3

4

5lihuideMacBook-Pro:Learn lihui$ gcc -o add add.c

lihuideMacBook-Pro:Learn lihui$ ./add

3 + 5 = 8

3 + 5 = 8

3 + 5 = 8

和前面部分一样,函数执行结果依然没有问题。所以,我们只要理解函数指针的基本使用方式,无论再复杂的函数指针调用问题,我们都可以轻松解决。

函数指针基本定义形式:函数返回值类型 (* 指针变量)(函数参数列表) = 函数地址

函数指针作为参数调用不同的函数

接下来,我们将通过一个例子来学习如何通过函数指针来调用不同的函数:1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23#include

int add(int a, int b){

return a + b;

}

int subtract(int a, int b){

return a - b;

}

int domath(int (* fun_name)(int, int), int x, int y) {

return fun_name(x, y);

}

int main(){

int a = 10, b = 5;

printf("a + b = %dn", domath(add, a, b));

printf("a - b = %dn", domath(subtract, a, b));

return 0;

}

在这里,我们首先定义了两个函数 int add(int, int) 、 int subtract(int, int),分别执行两个整数的加法与减法操作,接着定义了一个 int domath(int (* fun_name)(int, int), int, int) 函数,根据函数指针所指向的函数执行相关的操作。可以看到,domath 函数参数中,有一个指向带两个整形参数并且返回值为整形的函数的指针,而函数 int add(int, int) 和函数 int subtract(int, int) 恰好满足此特征,故通过函数名来分别调用这两种不同的方法是再好不过的了,domath 函数刚好实现了这一功能。

函数指针的这种灵活性在Linux内核的代码中得到充分体现,这种编码方式在Linux内核中比较常见,下面一段截取于 include/linux/netlink.h1

2

3

4

5

6

7

8

9

10

11...

struct netlink_dump_control {

int (*dump)(struct sk_buff *skb, struct netlink_callback *);

int (*done)(struct netlink_callback *);

void *data;

struct module *module;

u16 min_dump_alloc;

};

...

到此,我们对函数指针的学习就告一段落了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言中有两个相关概念,函数指针指针函数。 1. 函数指针(Function Pointers):函数指针是指向函数的指针变量。它可以用来存储和调用特定类型的函数。通过函数指针,可以在运行时动态地选择要执行的函数。函数指针的声明形式为:`返回类型 (*指针变量名)(参数列表)`。例如,以下是一个函数指针的示例: ```c #include <stdio.h> void display(int num) { printf("Number: %d\n", num); } int main() { void (*func_ptr)(int); // 声明一个函数指针变量 func_ptr = display; // 将函数的地址赋值给函数指针变量 func_ptr(10); // 通过函数指针调用函数 return 0; } ``` 2. 指针函数(Pointer to a Function):指针函数是一个返回指向函数的指针的函数。它返回的是函数的地址,而不是函数的返回值。指针函数的声明形式为:`返回类型 (*函数名)(参数列表)`。以下是一个指针函数的示例: ```c #include <stdio.h> int add(int num1, int num2) { return num1 + num2; } int subtract(int num1, int num2) { return num1 - num2; } int (*getOperation(char op))(int, int) { if (op == '+') { return add; // 返回add函数的地址 } else { return subtract; // 返回subtract函数的地址 } } int main() { int num1 = 10, num2 = 5; char op = '+'; int (*operation)(int, int); // 声明一个指针函数变量 operation = getOperation(op); // 将指针函数的返回值(函数地址)赋值给指针函数变量 int result = operation(num1, num2); // 通过指针函数调用对应的函数 printf("Result: %d\n", result); return 0; } ``` 以上就是函数指针指针函数的基本概念和用法。通过它们,可以实现更灵活的函数调用和动态选择执行的函数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值