文档详情

C结构体与函数指针的特殊应用.doc

发布:2018-05-30约2.51千字共3页下载文档
文本预览下载声明
C结构体与函数指针的特殊应用 ???? 在C++中,我们很容易就可以实现函数重载,特别是类的同名方法(多态)。那么,在C语言中我们可以有类似的应用吗? ???? 下面先给出我的说明代码,再做解释: //-----------------------------------------------------------// #include stdio.h struct A { // this is data int data; // this is operation void *(*function)(); }; void myfun1() { printf(this is fun()\n); return; } 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(void) { struct A a; a.function = (void *)myfun2; a.function(a); a.function = (void *)myfun3; a.function(a); return 0; } //-----------------------------------------------------------// 在GCC下编译运行的结果如下: //-----------------------------------------------------------// [zonwang@be-rdcnasbd1 test] cc -c -g fun_point.c [zonwang@be-rdcnasbd1 test] cc -o fun_point fun_point.o [zonwang@be-rdcnasbd1 test] ./fun_point this is fun(97) this is fun(a) //-----------------------------------------------------------// 现在分析一下上面的代码: 首先,这个程序的思路是想用一个结构体模拟一个类,通过函数指针来申明“类”方法,并模拟多态性。 ??? ??? 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) (s
显示全部
相似文档