函数指针的用法

1、

利用指针函数 和 回调函数 来 打印" Hello ",我们直接上码:

#include<iostream>void A()
{printf("Hello");
}
void B(void (*ptr)())
{ptr();
}int main()
{void (*p)() = A;B(p);
}

运行结果:

结果正确的,A通过 ptr() 回调 并 执行成功。

注意:

(1)

void B(void (*ptr)())
{ptr();
}

第一:这个函数B,将 指针函数 作为 参数。ptr 指向一个 没有参数 并且 返回空参数的 A函数。

第二:我们通过 ptr() 来调用任何东西函数。(A会通过 ptr() 来执行,打印出hello)

第三:我们通过指针函数 调用 函数 的这个语句是一个回调函数。

(2)

int main()
{void (*p)() = A;B(p);
}

第一:定义一个函数指针 把 地址A 传递给它。

第二:函数B 传递给它的 函数指针p。

第三:回调函数:当函数的引用传递给另一个函数时,那个特定的函数 被称为 回调函数(Callback Function). 所以,A是一个回调函数。它可以由B通过引用,通过函数指针回调。

这里也可以直接这么写:

int main()
{B(p);
}

2、

函数指针和回调函数 实际的运用

这个例子是把一维数组里面的数字按递增顺序进行排序。

#include<iostream>void BubbleSort(int *A, int n)
{int i,j,temp;for(i=0; i<n; i++)for(j=0; j<n-1; j++){if(A[j] > A[j+1]){temp = A[j];A[j] = A[j+1];A[j+1] = temp;}}
}int main()
{int i, A[] = {3,2,1,5,6,4};BubbleSort(A, 6);for(i= 0; i< 6;i++){printf("%d ",A[i]);}
}

运行结果:

如果有时候我有要递增,有些时候我又要递减,那该怎么办哦?写多一个排序函数吗?不! 我们使用回调来解决这个问题:

#include<iostream>int compare(int a , int b)
{if(a > b) return 1;else return -1;
}void BubbleSort(int *A, int n, int (*compare)(int,int))
{int i,j,temp;for(i=0; i<n; i++)for(j=0; j<n-1; j++){if(compare(A[j],A[j+1]) > 0){temp = A[j];A[j] = A[j+1];A[j+1] = temp;}}
}
int main()
{int i, A[] = {3,2,1,5,6,4};BubbleSort(A, 6, compare);for(i= 0; i< 6;i++) printf("%d ",A[i]);
}

运行结果:

注意:

(1)

void BubbleSort(int *A, int n, int (*compare)(int,int))
{......
}

BubbleSort函数 将 函数指针int (*compare)(int,int) 作为参数;

int (*compare)(int,int) 意义为:回调函数 或 该指针应指向的函数 必须取 两个整数为参数,而且它还会返回一个整数;

(2)

int compare(int a , int b)
{if(a > b) return 1;else return -1;
}

compare 是一个回调函数。

(3)

int main()
{int i, A[] = {3,2,1,5,6,4};BubbleSort(A, 6, compare);for(i= 0; i< 6;i++) printf("%d ",A[i]);
}

BubbleSort函数 加了参数:compare,这个是地址是传递给 BubbleSort函数的。也就是传递给 int (*compare)(int,int)。

这个时候我们要递增了,不用重新编码,直接修改函数即可:

#include<iostream>int compare(int a , int b)
{if(a > b) return -1;else return 1;
}void BubbleSort(int *A, int n, int (*compare)(int,int))
{int i,j,temp;for(i=0; i<n; i++)for(j=0; j<n-1; j++){if(compare(A[j],A[j+1]) > 0){temp = A[j];A[j] = A[j+1];A[j+1] = temp;}}
}int main()
{int i, A[] = {3,2,1,5,6,4};BubbleSort(A, 6, compare);for(i= 0; i< 6;i++) printf("%d ",A[i]);
}

运行结果:

注意:

(1)

int compare(int a , int b)
{if(a > b) return -1;else return 1;
}

修改这个地方即可:当 a > b 返回 -1;否则 返回 1;

3、

我们使用新的数组来排序,A[] = {-31,22,-1,50,-6,4};

#include<iostream>int compare(int a , int b)
{if(a > b) return -1;else return 1;
}
int absolute_compare(int a, int b)
{if(abs(a)>abs(b)) return 1;return -1;
}
void BubbleSort(int *A, int n, int (*compare)(int,int))
{int i,j,temp;for(i=0; i<n; i++)for(j=0; j<n-1; j++){if(compare(A[j],A[j+1]) > 0){temp = A[j];A[j] = A[j+1];A[j+1] = temp;}}
}int main()
{int i, A[] = {-31,22,-1,50,-6,4};BubbleSort(A, 6, absolute_compare);for(i= 0; i< 6;i++) printf("%d ",A[i]);
}

运行结果:

看来不起作用,因为我们写的冒泡排序只能对正数,我们使用 qsort()函数 来实现:

#include<iostream>
#include<algorithm>int compare(const void* a, const void* b)
{int A = *((int*)a);int B = *((int*)b);return A-B;
}int main()
{int i, A[] = {-31,22,-1,50,-6,4};qsort(A, 6, sizeof(int),compare);for(i= 0; i< 6;i++) printf("%d ",A[i]);
}

运行结果:

代码解析:

(1)

qsort(A, 6, sizeof(int),compare);

C++ 要调用qsort库要使用 #include<algorithm> 。

第一个参数:数组。第二个参数:数组长度。第三个参数:数据类型的大小。

第四个参数:函数指针。这个函数指针是指向比较函数的指针。

(2)

int compare(const void* a, const void* b)
{......
}

解析 比较函数: const void* a,这里的 const 是不能改变这个变量。

因为qsort函数的通用设计, 我们不得不使用void指针,void 是通用类型,我们可以将它们转换为任何数据类型的指针,这是qsort函数的规范;

记住,qsort可以对任何数组排序,而不仅仅是整型数组。只是,你必须给出比较逻辑。

(3)

int compare(const void* a, const void* b)
{int A = *((int*)a);int B = *((int*)b);return A-B;
}

怎么理解?????? 一步一步来。

int A = (int*)a;

你可以将此视为作为 void指针传递 的第一个元素的引用。

要获取元素,如果它是一个整数列表,我首先必须对 void指针 进行类型转换到 int指针。

然后我将不得不使用 * 运算符来指针取值:

int A = *((int*)a);

接下来要讲的是: return A-B;

如果A 的值 比B 的值 大,那就是递增排序,相反,则 递减排序。


有编过程的人的代码,比那些无知的人使用的软件更有价值。

C ++ 指针 | 指针与函数 实际运用_8相关推荐

  1. C++ 笔记(14)— 指针(指针声明、取地址、取值、new/delete、NULL指针、指针运算、指针数组、数组指针、指针传递给函数、从函数返回指针)

    1. 声明指针 指针是一个变量,其值为另一个变量的地址,即,内存位置的直接地址.就像其他变量或常量一样,您必须在使用指 针存储其他变量地址之前,对其进行声明. 指针变量声明的一般形式为: type * ...

  2. C指针6:指针变量作为函数参数

    在C语言中,函数的参数不仅可以是整数.小数.字符等具体的数据,还可以是指向它们的指针.用指针变量作函数参数可以将函数外部的地址传递到函数内部,使得在函数内部可以操作函数外部的数据,并且这些数据不会随着 ...

  3. C++成员变量指针和成员函数指针【The semantics of funcitons】

    原文:https://blog.csdn.net/laojiu_/article/details/68946915 (原文有笔误) 1. #include <cstdio> #includ ...

  4. 用指针、子函数的方法去一维数组中所有元素的平均值,并放在a[0]处

    <程序设计基础实训指导教程-c语言> ISBN 978-7-03-032846-5 p142 7.1.2 上级实训内容 [实训内容7]用指针.子函数的方法去一维数组中所有元素的平均值,并放 ...

  5. 多态指针访问虚函数不能被继承的类快速排序N皇后问题插入排序堆排序merge归并排序栈上生成对象两个栈实现一个队列...

    多态 /*1. 要想实现覆盖(重写)父类必须声明为virtual,子类可以不声明为virtual.-->FunB()2. 派生类重写基类的虚函数实现多态,要求函数名.参数列表.返回值完全相同.( ...

  6. 对C语言 结构指针变量做函数的参数 结构作为函数的参数

    一.结构指针变量做函数的参数 /* 用指针变量作函数参数进行传送,这时由实参传向形参的只是地址,从而减少了时间和空间的开销. */ /* 计算一组学生的平均成绩和不及格的人数,用结构指针变量作函数参数 ...

  7. 【C 语言】指针 与 数组 ( 指针 | 数组 | 指针运算 | 数组访问方式 | 字符串 | 指针数组 | 数组指针 | 多维数组 | 多维指针 | 数组参数 | 函数指针 | 复杂指针解读)

    相关文章链接 : 1.[嵌入式开发]C语言 指针数组 多维数组 2.[嵌入式开发]C语言 命令行参数 函数指针 gdb调试 3.[嵌入式开发]C语言 结构体相关 的 函数 指针 数组 4.[嵌入式开发 ...

  8. c语言键盘回调函数键盘的码,深入浅出剖析C语言函数指针与回调函数(三)

    前面两篇文章: http://blog.csdn.net/morixinguan/article/details/65494239 http://blog.csdn.net/morixinguan/a ...

  9. C++函数指针与回调函数

    [转自]cnblogs.com/chenyuming507950417/archive/2012/01/02/2310114.html 今天讨论下C/C++中的回调函数. 在理解"回调函数& ...

最新文章

  1. cesium多边形描边_Cesium专栏-地形开挖2-任意多边形开挖(附源码下载)
  2. Windows Updateエラー 80072EE2
  3. win10系统上抓包网卡的驱动总是失效怎么办?
  4. spring-mybatis.xml 访问html5,Spring mvc无xml配置及利用JdbcTemplate访问数据库
  5. Spark _12_每个网址的每个地区访问量 ,由大到小排序
  6. APPCAN学习笔记003---原生开发与HTML5技术
  7. 关于C++中ios::sync_with_stdio(false)
  8. oracle ORA-00001 违反唯一约束条件 SYS_C009225问题
  9. channel代码示例
  10. Tomcat SSL配置 Connector attribute SSLCertificateFile must be defined when using SSL with APR解决 作者:孤风一
  11. PDF编辑时怎样给PDF文件添加页码
  12. c语言调用函数的方法案例,C语言经典例题100例——C语言练习实例34解答(函数调用)...
  13. 从档案信息管理到档案知识管理
  14. [kuangbin带你飞]专题十二 基础DP1 题解+总结
  15. 先谈云计算再谈云大会
  16. 层次分析法AHP——清风老师
  17. 装修后才知道的一些事,无数RMB砸出来的经验 [转贴]
  18. Redis--个人记录
  19. usim卡如何换nano卡_5G 超级 SIM 卡发布,小内存手机有福了
  20. SiKi学院 Unity中常用api学习笔记(015-019)

热门文章

  1. 无码系列-1-架构师启蒙篇
  2. 小狼毫(Rime)输入法设置Shift直接上屏英文字符并切换为英文状态方法
  3. Script标签解决跨域
  4. VueSummary_note
  5. java程序包不存在_idea Error:(3, 32) java: 程序包***不存在的问题
  6. python 模拟浏览器selenium_Python使用Selenium模块模拟浏览器抓取斗鱼直播间信息示例...
  7. python fabric上传文件夹_通过python的fabric包完成代码上传部署(简单版)
  8. jssdk信息验证失败_阿里云环境中TLS/SSL握手失败的场景分析
  9. react 组件怎么公用_用 react 做一个跟随组件的 tooltip
  10. Docker安装与卸载,配置阿里云镜像加速器