函数指针

来源:互联网 发布:mac关闭盖子不断网 编辑:程序博客网 时间:2024/06/05 07:08
关于指针的话题很多,随随便便google一下,就有很多资源。下面这篇文章就可以给你科普一下
函数指针:http://blog.csdn.net/porscheyin/article/details/3461632
函数指针一直是C语言的一块难啃的骨头,本文主要关注c++11对此的语法糖

含有复杂返回值的函数
    在写一个函数之前,我们要搞明白函数的返回值是什么(数字、指针、自定义的结构体etc);我们假定返回值的类型是T,那么函数的声明一般为T func(。。。);其中。。。表示函数的参数。
        当我们分析一个函数时,通常是它的返回值非常复杂,从而导致我们难以迅速解析该函数。例如下面这段代码:
  1. #include<stdio.h> 
  2. int *(*get_addr(int* mat[][10], int index))[10]
  3. {
  4. return &mat[index];
  5. }
  6. int main()
  7. {
  8. int* m_mat[10][10] = {0};
  9. // 做一些你想做的事情
  10. int* (*ptr)[10] = get_addr(m_mat, 2);
  11. printf("*ptr size is %u\n", sizeof *ptr);
  12. for (int i=0; i<10; i++)
  13. printf("%p %p\n", &(*ptr)[i], &m_mat[2][i]); 
  14. return 0;
  15. }
        上面的get_addr函数的返回值有很多种推断方法,最简单的莫过于根据第四行的&mat[index]来分析。单独从函数名上,我们可以作如下考虑:
        1. typedef int* (*T)[10];
        2. 将函数改写为 T get_addr(int* mat[][10], int index)
        于是程序如下:
  1. #include<stdio.h> 
  2. typedef int* (*T)[10];
  3. T get_addr(int* mat[][10], int index)
  4. {
  5. return &mat[index];
  6. }
  7. int main()
  8. {
  9. int* m_mat[10][10] = {0};
  10. // 做一些你想做的事情
  11. int* (*ptr)[10] = get_addr(m_mat, 2);
  12. printf("*ptr size is %u\n", sizeof *ptr);
  13. for (int i=0; i<10; i++)
  14. printf("%p %p\n", &(*ptr)[i], &m_mat[2][i]); 
  15. return 0;
  16. }
        C++11标准提供了一种新的写法:
  1. #include<stdio.h>
  2. // c++ 11的支持需要vs2012 或者 gcc较新版本外加 -std=c++0x的支持
  3. auto get_addr(int* mat[][10], int index) -> int* (*)[10]
  4. {
  5. return &mat[index];
  6. }
  7. int main()
  8. {
  9. int* m_mat[10][10] = {0};
  10. // 做一些你想做的事情
  11. // int* (*ptr)[10] = get_addr(m_mat, 2);
  12. auto ptr = get_addr(m_mat, 2); // c++ 11
  13. printf("*ptr size is %u\n", sizeof *ptr);
  14. for (int i=0; i<10; i++)
  15. printf("%p %p\n", &(*ptr)[i], &m_mat[2][i]); 
  16. return 0;
  17. }
        在这里,我们发现函数的定义变得和以往有些不一样, 多了一个箭头,箭头右边是返回值类型。由于返回值类型在参数列表的右边写出,这样相对更加容易看明白。
函数指针
    指向函数的指针。
     如我们需要一个指向int *(*get_addr(int* mat[][10], int index))[10]的函数指针get_addr_ptr,我们仅仅需要将声明中的get_addr替换成(*get_addr_ptr)就可以了:
int *(* (*get_addr_ptr) (int* mat[][10], int index))[10]。
 如果你觉得麻烦,可以使用C++11的如下方法来替换:
autoget_addr_ptr = get_addr;
如果这还不够,比如和get_addr相同参数相同返回值的函数有很多个,需要动态绑定某个函数,这时候也可以这样写:
        auto (* get_addr_ptr)(int* mat[][10], int index) ->int* (*)[10]




























原创粉丝点击