函数指针数组c语言的用法,C语言中函数指针数组浅析

发现问题

问题分析

示例代码

发现问题

今天,在阅读Linux内核中关于socket的源代码时,遇到了下面一段代码:

struct proto_ops {

int family;

struct module *owner;

int (*release) (struct socket *sock);

int (*bind) (struct socket *sock,

struct sockaddr *myaddr,

int sockaddr_len);

int (*connect) (struct socket *sock,

struct sockaddr *vaddr,

int sockaddr_len, int flags);

int (*socketpair)(struct socket *sock1,

struct socket *sock2);

int (*accept) (struct socket *sock,

struct socket *newsock, int flags);

int (*getname) (struct socket *sock,

struct sockaddr *addr,

int *sockaddr_len, int peer);

unsigned int (*poll) (struct file *file, struct socket *sock,

struct poll_table_struct *wait);

int (*ioctl) (struct socket *sock, unsigned int cmd, unsigned long arg);

int (*listen) (struct socket *sock, int len);

int (*shutdown) (struct socket *sock, int flags);

int (*setsockopt)(struct socket *sock, int level,

int optname, char __user *optval, int optlen);

int (*getsockopt)(struct socket *sock, int level,

int optname, char __user *optval, int __user *optlen);

int (*sendmsg) (struct kiocb *iocb, struct socket *sock,

struct msghdr *m, size_t total_len);

int (*recvmsg) (struct kiocb *iocb, struct socket *sock,

struct msghdr *m, size_t total_len,

int flags);

int (*mmap) (struct file *file, struct socket *sock,

struct vm_area_struct * vma);

ssize_t (*sendpage) (struct socket *sock, struct page *page,

int offset, size_t size, int flags);

};

在这段代码中,我们注意到proto_ops结构体的成员包括下面这样的成员变量:

int (*release) (struct socket *sock);

这边是函数指针作为结构体成员变量的使用方法。

问题分析

首先,我们对C和C++中结构体以及C++类的区别进行一些说明:

C中的结构体和C++中结构体的不同之处:

在C中的结构体只能自定义数据类型,结构体中不允许有函数;

而C++中的结构体可以加入成员函数。

C++中的结构体和类的异同:

相同之处:

结构体中可以包含函数;也可以定义public、private、protected数据成员;定义了结构体之后,可以用结构体名来创建对象。但C中的结构体不允许有函数;也就是说在C++当中,结构体中可以有成员变量,可以有成员函数,可以从别的类继承,也可以被别的类继承,可以有虚函数。

不同之处:

结构体定义中默认情况下的成员是public,而类定义中的默认情况下的成员是private的。类中的非static成员函数有this指针,(struct中没有是错误的,一直被误导啊,经过测试struct的成员函数一样具有this指针),类的关键字class能作为template模板的关键字,而struct不可以。

实际上,C中的结构体只涉及到数据结构,而不涉及到算法,也就是说在C中数据结构和算法是分离的,而到C++中一类或者一个结构体可以包含函数(这个函数在C++我们通常中称为成员函数),C++中的结构体和类体现了数据结构和算法的结合。

因此,我们在阅读纯C代码时,应该注意代码中使用函数指针成员变量来等效地实现成员函数过程。

示例代码

这里,我们使用一段代码来对函数指针成员进行相关说明:

#include

#include

int func1(int n)

{

printf("func1: %d\n", n);

return n;

}

int func2(int n)

{

printf("func2: %d\n", n);

return n;

}

int main()

{

int (*a[2])(int);

a[0] = func1;

a[1] = func2;

a[0](1);

a[1](2);

return 0;

}

我们注意上面代码中的

int (*a[2])(int);

在这句代码中,我们定义了这样一个数组:

数组保存指针,什么样的指针呢?

形如 int func(int input) 的 func函数指针,形参为int变量,返回int变量。

因此,数组保存的是形参为单一int变量和返回值为int值得函数指针。

现在,我们定义了这样一个数组,然后

a[0] = func1;

a[1] = func2;

由于我们在main函数前声明和定义了func1和func2两个函数(这两个函数满足前面所提及的函数条件),这时,我们便可以使用这两个函数指针赋值函数指针数组。

然后,我们便可以使用数组成员来实现函数调用:

a[0](1);

a[1](2);

最终结果为:

0818b9ca8b590ca3270a3433284dd417.png

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值