zoukankan      html  css  js  c++  java
  • 函数指针

    我理解的函数指针:

      函数指针是一种指向一块代码区域的指针。就像struct,int char等对应的指针类型,只不过函数指针是指向一个函数。函数指针可以用来做为回调使用,也可以用来在C语言中模拟面向对象编程。函数指针的格式一般如下:

      int (*POINTER_NAME)(...)

    函数指针的demo:

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <errno.h>
      4 #include <string.h>
      5 
      6 void die(const char *message)
      7 {
      8     if(errno) {
      9         perror(message);
     10     } else {
     11         printf("ERROR: %s\n", message);
     12     }
     13     
     14     exit(1);
     15 }
     16 
     17 // a typedef creates a fake type, in this
     18 // case for a function pointer
     19 typedef int (*compare_cb)(int a, int b);
     20 
     21 /**
     22  * A classic bubble sort function that uses the
     23  * compare_cb to do the sorting.
     24  */
     25 int *bubble_sort(int *numbers, int count, compare_cb cmp)
     26 {
     27     int temp = 0;
     28     int i = 0;
     29     int j = 0;
     30     int *target = malloc(count * sizeof(int));
     31     
     32     if(!target) die("Memory error.");
     33     
     34     memcpy(target, numbers, count * sizeof(int));
     35     
     36     for(i = 0; i < count; i++) {
     37         for(j = 0; j < count - 1; j++) {
     38             if(cmp(target[j], target[j+1]) > 0) {
     39                 temp = target[j+1];
     40                 target[j+1] = target[j];
     41                 target[j] = temp;
     42             }
     43         }
     44     }
     45     
     46     return target;
     47 }
     48 
     49 int sorted_order(int a, int b)
     50 {
     51     return a - b;
     52 }
     53 
     54 int reverse_order(int a, int b)
     55 {
     56     return b - a;
     57 }
     58 
     59 int strange_order(int a, int b)
     60 {
     61     if(a == 0 || b == 0) {
     62         return 0;
     63     } else {
     64         return a % b;
     65     }
     66 }
     67 
     68 /**
     69  * Used to test that we are sorting things correctly
     70  * by doing the sort and printing it out.
     71  */
     72 void test_sorting(int *numbers, int count, compare_cb cmp)
     73 {
     74     int i = 0;
     75     int *sorted = bubble_sort(numbers, count, cmp);
     76     
     77     if(!sorted) die("Failed to sort as requested.");
     78     
     79     for(i = 0; i < count; i++) {
     80         printf("%d ", sorted[i]);
     81     }
     82     printf("\n");
     83     
     84     free(sorted);
     85 }
     86 
     87 
     88 int main(int argc, char *argv[])
     89 {
     90     if(argc < 2) die("USAGE: ex18 4 3 1 5 6");
     91     
     92     int count = argc - 1;
     93     int i = 0;
     94     char **inputs = argv + 1;
     95     
     96     int *numbers = malloc(count * sizeof(int));
     97     if(!numbers) die("Memory error.");
     98     
     99     for(i = 0; i < count; i++) {
    100         numbers[i] = atoi(inputs[i]);
    101     }
    102     
    103     test_sorting(numbers, count, sorted_order);
    104     test_sorting(numbers, count, reverse_order);
    105     test_sorting(numbers, count, strange_order);
    106     
    107     free(numbers);
    108     
    109     return 0;
    110 }

    运行结果:

    1 zhaoscmatoMacBook-Pro:c zhaosc$ ./ex18
    2 ERROR: USAGE: ex18 4 3 1 5 6
    3 zhaoscmatoMacBook-Pro:c zhaosc$ ./ex18 4 2 1 9 7
    4 1 2 4 7 9 
    5 9 7 4 2 1 
    6 4 2 9 7 1 

    分析:

    在程序中定义die(...)方法,这个主要就是用于启动程序错误提示。

    使用typedef定义函数指针,其实这个就是把函数指针定义成一个类型,就像我们熟悉的struct。

    在int *bubble_sort(int *numbers, int count, compare_cb cmp)函数中使用了我们定义的类型compare_cb,变量可以为我们真正操作的函数,在main函数中我们把之前定义的函数sorted_order,reverse_order,strange_order函数作为参数传递给test_sorting。这里其实很好理解,我们定义的每个函数其实在内存都有具体的位置,而函数名就指向一块内存的起始位置。仔细一想函数指针其实就是指针之间的赋值。(这个我的理解,不清楚是否存在问题)。

     

    附带:

    随便说下指针函数,这两个概念名字很相似,容易被弄混。指针函数,相对简单,只不过是一个很普通的函数,唯一不同的是这个函数的返回值是一个指针。

    想一想,函数指针,和指针函数,配合可以写出很奇妙的代码,不过个人感觉使用它们的时候注释真的要写清楚,要不想我这样对C/C++了解不多的人读起代码来还真的有点吃力。前段时间一直在移植spice-space到Android平台下,源码中写的很复杂,其中就是使用了很多函数指针,当时看的我真的有点头晕目眩,最近补充了些C/C++的基础,感觉好多啦。

    Note:如博文中存在问题,请大家及时指出,我会及时纠正,谢谢。

  • 相关阅读:
    declaration may not appear after executable statement in block
    linux 管道通信
    用c语言创建双向环形链表
    bash: ./LM35_make_fs: Permission denied 解决办法
    sunzl is not in the sudoers file.This incident will be reported
    基于嵌入式linux路由转发功能的实现
    关于eth0 eth0:1 和eth0.1关系介绍
    软重启
    Android中Serializable和Parcelable序列化对象详解
    公共技术点(Android 动画基础)
  • 原文地址:https://www.cnblogs.com/zhaosc/p/3060758.html
Copyright © 2011-2022 走看看