指针真是让人又爱又恨。。。。。

首先还是先来看一下C语言中的高级指针声明。不要被表面迷惑最重要。

/*
** 《C和指针》——高级指针话题
*/ int i; //定义一个整型变量
int *pi; //指向整型变量的指针
int **ppi; //指向一个指针,而那个指针又指向一个整型变量 /*高级声明*/ int fun(); //普通函数声明,返回一个整数 int *fun(); //首先他是一个函数,但是他想返回一个指向整型的指针 int (*fun)(); //这就是一个指针了,他指向一个返回整型的函数,这个fun叫做“函数指针”,指向函数的指针 int *(*fun)(); //这个和上面那个差不多嘛,函数指针喽,只是这个函数返回一个指向整型的指针。 int f[]; //这是一个整型数组啊 int *f[]; //这也是一个数组,因为下标的优先级高,只不过这个数组里面都是指向整型的指针啊 int f()[]; //非法操作 int f[](); //非法操作 int (*f[])(); //首先他是一个数组,数组里面全是指针,这些指针指向返回值为整型的函数。 int *(*f[])(); //和上面一样,只不过这个函数返回整型指针。

函数指针:主要用途是实现“回调函数”和“转移表”

(1)、回调函数:把一个函数指针作为参数传递给其他的函数。

在《C与指针》中,作者指出:任何时候,如果你所编写的函数必须能够在不同的时刻执行不同类型的工作,或者执行只能由函数调用者定义的工作,都可以使用回调函数。许多窗口系统使用回调函数连接过个动作,如拖拽鼠标和点击按钮来指定程序中的某个特定的函数。

比如我们我们平时写的查找函数,每一个查找函数只能查找某一类型的数据,int型、char型,但是有没有一种函数能查找所有类型的数据呢?这时就需要函数指针来编写一个回调函数了。

首先调用者需要编写一个函数,用来比较两个值,然后把一个指向这个函数的指针作为参数传递给查找函数,然后查找函数调用你编写的那个函数来进行查找。

其实这个样子就像是,查找函数像是一个分拣机,你编写的比较函数可以比喻成分拣机上的传感器,给他一个能识别黑色的传感器,那么分拣机就会只把黑色的东西分拣出来,给他一个识别红色的传感器,就把红色的东西给分拣出来。

下面这个例子是《C和指针》里面,作者给出的链表中查找的例子:

/*
** 在一个单链表中查找一个指定值
*/
node *search_list(node *node_,void const *value,int (*compare)(void const *,void const *))
{
while(node_ != NULL)
{
if(compare(&node_->value,value) == )
break;
node_ = node_->link;
}
return node_;
} /*
** 用户可以自定义自己的比较函数
** 比较整型就强制转换为整型
*/
int compare(void const *a,void const *b)
{
if(*(int *)a == *(int *)b)
return ;
else
return ;
}

调用方式:

/*
** 回调函数的调用方式
** 因为函数名本身就是地址,所以并不需要取地址,不过也可以。
*/
discard_node = search_list(root,&desired_value,compare_ints) ;

这位博主也说了一下回调函数的一个作用——开发者可以将自己实现的函数细节进行封装,然后将头文件提供给用户。

https://blog.csdn.net/morixinguan/article/details/65494239

(2)、转移表:就是函数指针数组,他把具体操作和和选择操作的代码分离,是程序结构更加突出。

比如我们有时可能需要在switch语句中调用函数,当情况很多的时候,这个switch语句将会很长,如果表示操作符的代码是从0开始的连续整数,这时我们就可以使用转移表来代替switch语句来实现不同情况的函数选择。

还是直接来看例子:

/*
** 利用转移表实现多个函数的选择
*/
double add(double,double);
double sub(double,double);
double mul(double,double);
double div(double,double);
//......... double (*oper_fun[])(double,double) = {
add,sub,mul,div......
}

转移表的调用方式:

result = oper_fun[fun_num](num1,num2);

特别注意:使用转移表要特别注意下标的越界检查,保证下标位于合法的范围。

当然,上面提到的回调函数与转移表都只是很简单的应用,目的在于理解最基本的操作与原理。

《C与指针》——高级指针话题的更多相关文章

  1. C和指针 第十三章 高级指针话题

    高级声明: int (*f)(); 这里声明有两个括号,第二个括号是函数调用,第一个括号是聚组作用.(*f)是一个函数,所以f是指向返回整型的函数的指针.程序中的每个函数都位于,内存中某个位置,所以存 ...

  2. C的指针疑惑:C和指针13(高级指针话题)上

    int *f(); f为一个函数,返回值类型是一个指向整形的指针. int (*f)(); 两对括号,第二对括号是函数调用操作符,但第一对括号只起到聚组的作用. f为一个函数指针,它所指向的函数返回一 ...

  3. C语言07指针高级

    01内存四区 接口封装和设计思想引导 接口封装设计思想引导 Sckclient客户端api模型设计 第一套api函数 #ifndef _SCK_CLINT_H_ #define _SCK_CLINT_ ...

  4. C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | IT宅.com

    原文:C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | IT宅.com C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | I ...

  5. C++(指针和高级指针)-上篇

    [在指针中存储地址] int *pAge=nullptr; //将PAge声明为int指针,即用于存储int变量的地址 如果将指针初始化为0或者NUll,以后必须将变量的地址赋给它,如下例代码: ; ...

  6. 联合与枚举 、 高级指针 、 C语言标准库(一)

    1 输入一个整数,求春夏秋冬 1.1 问题 在实际应用中,有的变量只有几种可能取值.如人的性别只有两种可能取值,星期只有七种可能取值.在 C 语言中对这样取值比较特殊的变量可以定义为枚举类型.所谓枚举 ...

  7. [c/c++] programming之路(17)、高级指针

    一.二级指针 二级指针的作用:1.函数改变外部变量指针2.外挂改变一个指针的值 #include<stdio.h> #include<stdlib.h> void main() ...

  8. 理清C++常量指针和指针常量这团乱麻

    写在前面: 与其说C++中的常量指针和指针常量是一块很有嚼头的语法糖,不如说它是一块相当难啃的骨头.其实本来没什么,这无非是const int *p与int* const p的区别, 但一涉及到起名字 ...

  9. 数组指针与指针数组(good)

    数组指针和指针数组的区别 数组指针(也称行指针) 定义 int (*p)[n]; ()优先级高,首先说明p是一个指针,指向一个整型的一维数组,这个一维数组的长度是n,也可以说是p的步长.也就是说执行p ...

随机推荐

  1. 小波变换——哈尔小波,Haar

    哈尔小波转换是于1909年由Alfréd Haar所提出,是小波变换(Wavelet transform)中最简单的一种变换,也是最早提出的小波变换. Alfréd Haar,1885~1933,匈牙 ...

  2. Python集成开发环境PyCharm调试

    Run/Debug配置: 设置断点:在行号后单击(再单击取消) 启动调试:Shift+F9 单步执行:F8 进入函数:F7 跳出函数:Shift+F8 运行到下一个断点:F9 调试中查看: 退出调试: ...

  3. Apache伪静态配置,支持.htaccess配置方法

    第一.编辑httpd.conf文件 A - 在etc/httpd/conf/目录下的httpd.conf 文件,找到: LoadModule rewrite_module modules/mod_re ...

  4. java 实现类似于python requests包的Session类,自动管理cookie。

    1.在py中requests.post()和get()函数都是在那个函数内部里面自动生成了一个Session类的实例,所以requests,post和get函数要想干登陆后才能干的事情,需要添加coo ...

  5. 关于Android中Animation的停止【转载】

    转载自:http://blog.csdn.net/easonx1990/article/details/8231520 最近遇到一个需求,通过在GridView上改变焦点,并且GridView上每个i ...

  6. html5页面平滑切换实现以及问题(20160120更新)

    注:本文是基于手机端 Hybrid APP 讨论,而不是普通的PC端网页 >> 之前的页面跳转方式: 比如有这两个页面:A.html  B.html,  A B 是纯HTML实现,没有采用 ...

  7. Java Jdk1.8 HashMap源代码阅读笔记二

    三.源代码阅读 3.元素包括containsKey(Object key) /** * Returns <tt>true</tt> if this map contains a ...

  8. 05-Vim命令合集

    Vim命令合集 命令历史 以:和/开头的命令都有历史纪录,可以首先键入:或/然后按上下箭头来选择某个历史命令. 启动vim 在命令行窗口中输入以下命令即可 vim 直接启动vim vim filena ...

  9. nessus 激活码

    nessus激活码的申请 nessus屏蔽了中国的激活码申请,中国IP申请的时候会直接跳转到购买商业版的页面. 解决方法: 使用IE代理或者VPN,用美国的IP最好,然后访问网址: http://ww ...

  10. 解决node里面的中文乱码

    今天咋学习node的时候,跟着视频里在撸代码,但是却出现了中文乱码的情况,视频中的谷歌浏览器可能和我的版本不一致,先看代码吧: 'use strict'; const http = require(& ...