文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>C函数指针剖析与应用

C函数指针剖析与应用

时间:2010-09-16  来源:biti-leaf

    前几天,在写一个关于hash算法的测试程序,程序的主要功能就是一次要测四组数据,每组的hash函数都不一样,这里用h1,h2,h3,h4代替,hash函数的输入是一样的,四组数据分别定义了4个hash表,这样,插入表的操作,我定义了一个函数insert_hash(hash_table, data, ...),这样有利于代码的重用,但是这里遇到的一个问题是,由于插入到每个表中的hash函数是不一样的,那如何在insert_hash函数中区分这种情况呢?即插入到第一个表用h1函数,第二个表用h2函数...。这里我用的方法是加了一个参数type,type的取值为1,2,3,4,分别代表h1,h2,h3,h4。即type为1时,表示要插入第一表,要利用h1函数....。这样问题就解决了。
    虽然,问题解决了,但是我的思考并没有结束。这里只有4个hash函数,如果有100个hash函数呢?难道我要在我的程序里判断100次吗?

if(type == 1)
    ...
else if(type == 2)
    ...
    .
    .
    .
else if(type == 100)
    ...

     显然,这是不可能的。那有没有简单的方法呢?
     C语言的精髓在于指针,那函数指针或许可以。
     记得我第一次看到函数指针时,那是在大二上的《数据结构》课上,当时,老师讲到遍历二叉树,我清楚的记得当时书上将打印二叉树节点的信息的函数是作为一个指针传递给遍历函数的。当时,我并不理解,而且,老师也说,这个你们不用深究,用处不大.....。
     这个设计是非常合理的,便于代码的重用,因为我们不知道二叉树节点中的存了什么类型的信息,可能是int,可能是char,可能是string,更有可能是别的数据结构等等,这样,每当我们要遍历存储不同信息的二叉树时,只需要修改打印函数即可!!!
    现在想想,真想对那个老师说,老师,你骗了我不是一次两次,而是四年!以后要是有可能教书,我一定教C语言。
    这里,我写了一个简单的例子。
    问题描述:写一个打印函数,能够打印不同类型的数组,如int、char等
    解决方案:
    1)我们首先要写出分别打印int和char数组内容的函数

void print1(void *a, int n)
{
    int *p;
    int i;
    p = (int *)a;
    for(i=0; i<n; i++)
    {
        printf("number:%d\n", p[i]);
    }
}
void print2(void *a, int n)
{
    char *p;
    int i;
    p = (char *)a;
    for(i=0; i<n; i++)
    {
        printf("char:%c\n", p[i]);
    }
}

注:void类型的功能堪比瑞士军刀!!!

2)定义一个接口函数。
 

void print_array(void *p, int n, void (*print)(void *, int))
{
    print(p, n);
}

注:具体的细节我就不多说了,自己看书吧
3)测试函数

int main()
{
    int a[] = {1,2,3,4,5};
    char b[] = "abcde";
    print_array(a, 5, &print1);
    print_array(b, 5, &print2);
    
    return 1;
}

4)程序输出:
[root@localhost c]# vi func.c
[root@localhost c]# gcc func.c -o func
[root@localhost c]# ./func
number:1
number:2
number:3
number:4
number:5
char:a
char:b
char:c
char:d
char:e
   注:其实我们可以利用typedef做个定义
   typedef void(*p_print)(void *, int);
   print_array函数就可以改成void print_array(void *p, int n, p_print print)
   这样,无论我们到打印什么类型,只要将写好相关的打印函数,然后把函数作为参数传给print_array函数即可。
   这里,或许有些人会说,那何必这么麻烦,我直接调用print1(a,5)和print2(b,5)不就行了,何必多此一举呢?遇到这种人,我只能对他说,真正编了几万行的C语言代码之后再跟我谈论这个问题吧。
相关阅读 更多 +
排行榜 更多 +
辰域智控app

辰域智控app

系统工具 下载
网医联盟app

网医联盟app

运动健身 下载
汇丰汇选App

汇丰汇选App

金融理财 下载