//C语言技巧--在结构体中使用函数例子(定义一个指向函数的指针) .
#include <stdio.h>
#include <malloc.h>
#include <memory.h>
#define DECLARATION int (*ptr)(int x,int y)
#define DEFINITION(x,y) ptr(x,y)
int sum(int x,int y)
{
printf("x:%d\n",x);
printf("y:%d\n",y);
return(x+y);
}
typedef struct {
int r;
// DECLARATION;
int (*ptr)(int x,int y);
} mystr;
void main()
{
int a,b,c;
scanf("%d,%d",&a,&b);
mystr stru;
stru.ptr=sum;
c=stru.ptr(a,b);
printf("a=%d,b=%d,sum=%d\n",a,b,c);
/* mystr *stru1; */
/* stru1=(mystr *)malloc(sizeof(mystr)); */
/* memset(stru1,0,sizeof(mystr)); */
/* c=stru1->DEFINITION(a,b); */
/* //c=stru->ptr(a,b); */
/* printf("a=%d,b=%d,sum=%d\n",a,b,c); */
/* memset(stru1,0,sizeof(mystr)); */
/* free(stru1); xz */
}
保存文件到struct_fun.c
编译:gcc -g -o struct_fun struct_fun.c
运行: ./struct_fun
2、
函数指针作为结构体成员 - [C语言]
2011-05-05
版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
http://cnmcu.blogbus.com/logs/125730496.html
今天在看《C\C++快速进阶教程》,看到一个“函数指针作为结构体成员”的程序,功能近似C++中的类中的成员函数,用那样的一种方法可实现定义的结构变量具有了方法的特性。
程序如下(下面的程序运行于WinTC):
#include "stdio.h"
struct aa
{
int a;
int( *fun)(int,int);
};
int add(int x,int y);
main()
{
struct aa bb;
int cc;
printf("%x\t",add);
bb.a=1000;
bb.fun=add;
cc=bb.fun(3,5);
printf("%d\t",cc);
printf("%x\t",bb.fun);
getch();
}
int add(int x,int y)
{
return x+y;
}
刚开始一看,觉得很茫然,是前所未见呀,很多教科书上也没讲,于是上百度搜了下,还真有怎么回事。找到一些资料,觉得很不错,贴出来分享一下:
++++++++++++++++++++++++++++++++++++++++++++++++++++++
函数指针作为结构体成员,实现函数注册 作者:admin 日期:2010-02-04
有时我们需要将函数作为结构体的成员,模拟C++类的情形,可应用于方法注册。
#include
struct a
{
void (*func)(char *);
};
void hello(char *name)
{
printf ("hello %s\n",name);
}
int main()
{
struct a a1;
a1.func = hello;
a1.func("illusion");
system("PAUSE");
return 0;
}
#############################################################################################################
标 题:
阅读权限:公众公开私有好友公开
文章类型:原创 转载
文章关键词(选填): 从已有的关键词中选择
文章摘要(选填):查看文章摘要 struct file_operations {int (*seek) (struct inode * ,struct file *, off_t ,int);int (*read) (struct inode * ,struct file *, char ,int);int (*readdir) (struct inode * ,struct file *, struct dirent * ,int);int (*ioctl) (struct inode * ,struct file *, unsined int ,unsigned longint (*mmap) (struct inode * ,struct file *, struct vm_area_struct *);int (*fasync) (struct inode * ,struct file *,int); 确 定取 消
文章正文:
在C++中,我们很容易就可以实现函数重载,特别是类的同名方法(多态)。那么,在C语言中我们可以有类似的应用吗?
呵呵,今天我找到了一种。
下面先给出我的说明代码,再做解释:
//-----------------------------------------------------------//
#include
struct A
{
void* (*fun)();
};
void myfun1()
{
printf("this is fun()\n");
}
int myfun2(int a)
{
printf("this is fun(%d)\n",a);
return a;
}
char myfun3(int a)
{
printf("this is fun(%c)\n",a);
return a;
}
int main()
{
struct A a;
a.fun=myfun2;
printf("AAA %d\n",a.fun());
printf("AAA1 %d\n",a.fun(4));
printf("AAA2 %d\n",a.fun(43,"32423"));
a.fun=myfun3;
printf("AAA %d\n",a.fun());
printf("AAA1 %d\n",a.fun(4));
printf("AAA2 %d\n",a.fun(43,"32423"));
return 0;
}
//-----------------------------------------------------------//
在GCC4.0下编译运行的结果如下:
//-----------------------------------------------------------//
hill@hill-laptop:~/Desk/temp$ gcc test4.c
test4.c: 在函数 ‘main’ 中:
test4.c:25: 警告:从不兼容的指针类型赋值
test4.c:30: 警告:从不兼容的指针类型赋值
hill@hill-laptop:~/Desk/temp$ ./a.out
this is fun(-1208768727)
AAA -1208768727
this is fun(4)
AAA1 4
this is fun(43)
AAA2 43
this is fun(
AAA -11
this is fun()
AAA1 4
this is fun(+)
AAA2 43
hill@hill-laptop:~/Desk/temp$
//-----------------------------------------------------------//
现在分析一下上面的代码:
首先,这个程序的思路是想用一个结构体模拟一个类,通过函数指针来申明“类”方法,并模拟多态性。
void* (*fun)();--------(1)
是一个函数指针,注意,这里不要写成
void (*fun)();--------(2)
接下来写了两个函数
void myfun1();
int myfun2(int);
在接下来的main函数中,我们为A实例a的fun域赋值,这里我们直接赋值了myfun2,若上面方法申明中采用(2),那么将不能把myfun2赋值给fun,因为void*是可以指向任何类型的指针,那么当然可以指向int。这里又定义了myfun3就是为类看看void*是否能自动的转化为char类型了。
另外要说明的一点就是,调用a.fun时我实验了几种调用方法,如程序中所示,它对行参没有任何要求,在本例中,由于传入的是myfun2(int),若不加任何参数调用a.fun(),那么输入的int将随机而定;若参数多于两个,则只有第一个参数有效,其余参数被呼略掉;若第一个参数与所传入的函数不匹配,则虽然可以通过编译,但结果一般会与期望的不同(错误)。
那么,它是否是多态呢?显然不是的,多态是个运行时概念,若想在C里面用同名函数则必须如此利用函数指针,在使用不同的重载形式前必须给函数指针赋上相应的函数才行,在本例中,若要用重载型myfun3的话,在调用a.fun(...)前必须有这样一行
a.fun=myfun3;
这是因为C毕竟还是一个静态语言的原因。
这种结构体与函数指针的结合使用还有很多用途,其实也可以将公用体与函数指针结合,方法一样。这几种结合功能相当强大。在定义接口时将非常有用。
比如在写一个设备驱动程序时,我们就要填写一个数据结构file_operations,具体的定义如下:
struct file_operations {
int (*seek) (struct inode * ,struct file *, off_t ,int);
int (*read) (struct inode * ,struct file *, char ,int);
int (*write) (struct inode * ,struct file *, off_t ,int);
int (*readdir) (struct inode * ,struct file *, struct dirent * ,int);
int (*select) (struct inode * ,struct file *, int ,select_table *);
int (*ioctl) (struct inode * ,struct file *, unsined int ,unsigned long
int (*mmap) (struct inode * ,struct file *, struct vm_area_struct *);
int (*open) (struct inode * ,struct file *);
int (*release) (struct inode * ,struct file *);
int (*fsync) (struct inode * ,struct file *);
int (*fasync) (struct inode * ,struct file *,int);
int (*check_media_change) (struct inode * ,struct file *);
int (*revalidate) (dev_t dev);
}
这个数据结构为编程人员提供了一个访问设备的公用接口,比如read,write等等。
具体设备驱动程序的编写已经超出本文范围,日后再说明。
小结:
利用函数指针来模拟多太,讨论出函数指针的一些特殊用法。以及调用函数指针的参数无关性。
#############################################################################################################
#include "stdio.h"
struct DEMO //遥控器实体
{
char x; // 按键
int (*func)(int x,int y); //函数指针 //按按键
};
int add2(int x,int y) //定义遥控器发送指令
{
return x+y;
}
int dec2(int x,int y) //定义遥控器发送指令
{
return x-y;
}
struct DEMO demo[2] =
{
{1,add2}, {2,dec2}
};
int main(void)
{
printf("func%d=%d\n",demo[0].x,demo[0].func(4,3));
printf("func%d=%d\n",demo[1].x,demo[1].func(4,3));
return 0;
}
说明:demo[0],demo[1]可以看做两种不同功能的遥控器实体,
demo[0].x为获取遥控器的固有属性,可以是遥控器的品牌
demo[0].func(4,3)可以抽象为同时按下4,3按键后遥控器的反应;
+++++++++++++++++++++++++++++++++++++++++++++++++++++
大致就是这样。2011/05/05
http://blog.csdn.net/rjs123/article/details/7655319