c语言函数指针常用吗,C语言中函数指针的声明及使用

66b52468c121889b900d4956032f1009.png

8种机械键盘轴体对比

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

函数指针一般的声明方式为:1Return (* pf)(Params);

其中Return代表返回值的类型,Params代表函数参数列表,如下面两个比较简单的声明:1

2void (* pf1)(int, char *);

int * (* pf2)(void);

使用的时候可以使用以下两种等价的赋值及调用方式:1

2

3

4

5

6

7pf = FunctionName;

pf = &FunctionName;

// Call

pf();

(*pf)();

更为复杂一点的问题是,如果一个函数指针作为函数的参数与函数的返回值时该如何进行声明呢?

作为函数参数的情况比较简单,像这样处理即可:1

2

3

4

5

6void (void (*)(int, int), int, int);

void (void (* pf)(int, int), int a, int b)

{

return pf(a, b);

}

这个例子中,声明并定义了一个函数Fun(),这个函数接受3个参数,后两个参数为int,第一个参数的类型是void (*)(int, int),这是一个函数指针,指向一个返回值为void,参数为两个int的函数。

然而如何处理函数指针作为返回值的情况呢?标准库中的signal()函数就是一个这样的函数,其声明形式如下:1void (* signal(int sig, void (* handler)(int)))(int);

这个函数声明一眼看过去不是很好懂,下面来仔细分析一下。

如果我们要声明一个整形变量a,可以这样写:1int a;

如果要改为声明一个返回值为整形的函数fun(),可以视为只要将声明变量时使用的a改为fun()即可,即1int fun();

用同样的思路来分析声明一个返回值为函数指针的函数的声明方法,只要将函数指针声明中的变量名部分换为函数体即可。用实例分析一下:1void (* pf)(int);

这里面pf是一个函数指针,指向一个输入参数为int,返回值为void的函数。将其中的pf换为一个函数fun(),即1void (* fun())(int);

这样就得到了一个返回值为函数指针的函数fun(),它返回的函数指针其实就是上面的pf。

理解了这样的声明方式后再来看signal()函数的声明就不那么难理解了。先看最里层:1void (* handler)(int)

这是一个函数指针handler,带一个int参数,返回值为空。

再向外一层:1signal(int sig, void (* handler)(int))

这是一个函数signal(),其参数为一个整形和一个函数指针。那这个函数的返回值是什么呢?由上面的分析易知,也是一个函数指针,这个函数指针的原型是这样的:1void (* Returnpf)(int);

对比Returnpf和handler的声明,可以看到二者是完全一样的。这时候就可以利用typedef这个好东西来简化之前那个复杂的signal()函数的声明了,具体做法如下:1

2

3

4

5void (* signal(int sig, void (* handler)(int)))(int);

typedef void (* sighandler_t)(int);

sighandler_t signal(int sig, sighandler_t handler);

其中第1行与第5行的声明是完全等价的,使用第5行这种声明方式就显得直观多了。

最后编写了两个简单的测试程序来进一步熟悉下函数指针的使用方法。

不使用typedef的版本: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// Function declaration

void PrintStr(char *(*)(void));

char *(* Run(int, int, int (*)(int, int)))(void);

char * Msg1(void)

{

return "Great than 0!rn";

}

char * Msg2(void)

{

return "Less than 0!rn";

}

void PrintStr(char *(* Fun)(void))

{

puts(Fun());

}

int Sum(int a, int b)

{

return a + b;

}

char *(* Run(int a, int b, int (* SumFun)(int, int)))(void)

{

if(SumFun(a, b) >= 0)

return Msg1;

else

return Msg2;

}

int main()

{

PrintStr(Run(1,2,Sum));

PrintStr(Run(-1,-2,Sum));

return 0;

}

使用typedef的版本: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

42

43

44

45// Typedef

typedef int (* MySumFun)(int, int);

typedef char * (* MyCharFun)(void);

// Function declaration

void PrintStr(MyCharFun);

MyCharFun Run(int, int, MySumFun);

char * Msg1(void)

{

return "Great than 0!rn";

}

char * Msg2(void)

{

return "Less than 0!rn";

}

void PrintStr(MyCharFun Fun)

{

puts(Fun());

}

int Sum(int a, int b)

{

return a + b;

}

MyCharFun Run(int a, int b, MySumFun Fun)

{

if(Fun(a, b) >= 0)

return Msg1;

else

return Msg2;

}

int main()

{

PrintStr(Run(1,2,Sum));

PrintStr(Run(-1,-2,Sum));

return 0;

}

程序运行输出结果均为:1

2

3Great than 0!

Less than 0!

使用typedef的版本明显可读性要好得多。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值