C ++ 指针 | 指针与函数 实际运用_8
函数指针的用法
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相关推荐
- C++ 笔记(14)— 指针(指针声明、取地址、取值、new/delete、NULL指针、指针运算、指针数组、数组指针、指针传递给函数、从函数返回指针)
1. 声明指针 指针是一个变量,其值为另一个变量的地址,即,内存位置的直接地址.就像其他变量或常量一样,您必须在使用指 针存储其他变量地址之前,对其进行声明. 指针变量声明的一般形式为: type * ...
- C指针6:指针变量作为函数参数
在C语言中,函数的参数不仅可以是整数.小数.字符等具体的数据,还可以是指向它们的指针.用指针变量作函数参数可以将函数外部的地址传递到函数内部,使得在函数内部可以操作函数外部的数据,并且这些数据不会随着 ...
- C++成员变量指针和成员函数指针【The semantics of funcitons】
原文:https://blog.csdn.net/laojiu_/article/details/68946915 (原文有笔误) 1. #include <cstdio> #includ ...
- 用指针、子函数的方法去一维数组中所有元素的平均值,并放在a[0]处
<程序设计基础实训指导教程-c语言> ISBN 978-7-03-032846-5 p142 7.1.2 上级实训内容 [实训内容7]用指针.子函数的方法去一维数组中所有元素的平均值,并放 ...
- 多态指针访问虚函数不能被继承的类快速排序N皇后问题插入排序堆排序merge归并排序栈上生成对象两个栈实现一个队列...
多态 /*1. 要想实现覆盖(重写)父类必须声明为virtual,子类可以不声明为virtual.-->FunB()2. 派生类重写基类的虚函数实现多态,要求函数名.参数列表.返回值完全相同.( ...
- 对C语言 结构指针变量做函数的参数 结构作为函数的参数
一.结构指针变量做函数的参数 /* 用指针变量作函数参数进行传送,这时由实参传向形参的只是地址,从而减少了时间和空间的开销. */ /* 计算一组学生的平均成绩和不及格的人数,用结构指针变量作函数参数 ...
- 【C 语言】指针 与 数组 ( 指针 | 数组 | 指针运算 | 数组访问方式 | 字符串 | 指针数组 | 数组指针 | 多维数组 | 多维指针 | 数组参数 | 函数指针 | 复杂指针解读)
相关文章链接 : 1.[嵌入式开发]C语言 指针数组 多维数组 2.[嵌入式开发]C语言 命令行参数 函数指针 gdb调试 3.[嵌入式开发]C语言 结构体相关 的 函数 指针 数组 4.[嵌入式开发 ...
- c语言键盘回调函数键盘的码,深入浅出剖析C语言函数指针与回调函数(三)
前面两篇文章: http://blog.csdn.net/morixinguan/article/details/65494239 http://blog.csdn.net/morixinguan/a ...
- C++函数指针与回调函数
[转自]cnblogs.com/chenyuming507950417/archive/2012/01/02/2310114.html 今天讨论下C/C++中的回调函数. 在理解"回调函数& ...
最新文章
- cesium多边形描边_Cesium专栏-地形开挖2-任意多边形开挖(附源码下载)
- Windows Updateエラー 80072EE2
- win10系统上抓包网卡的驱动总是失效怎么办?
- spring-mybatis.xml 访问html5,Spring mvc无xml配置及利用JdbcTemplate访问数据库
- Spark _12_每个网址的每个地区访问量 ,由大到小排序
- APPCAN学习笔记003---原生开发与HTML5技术
- 关于C++中ios::sync_with_stdio(false)
- oracle ORA-00001 违反唯一约束条件 SYS_C009225问题
- channel代码示例
- Tomcat SSL配置 Connector attribute SSLCertificateFile must be defined when using SSL with APR解决 作者:孤风一
- PDF编辑时怎样给PDF文件添加页码
- c语言调用函数的方法案例,C语言经典例题100例——C语言练习实例34解答(函数调用)...
- 从档案信息管理到档案知识管理
- [kuangbin带你飞]专题十二 基础DP1 题解+总结
- 先谈云计算再谈云大会
- 层次分析法AHP——清风老师
- 装修后才知道的一些事,无数RMB砸出来的经验 [转贴]
- Redis--个人记录
- usim卡如何换nano卡_5G 超级 SIM 卡发布,小内存手机有福了
- SiKi学院 Unity中常用api学习笔记(015-019)
热门文章
- 无码系列-1-架构师启蒙篇
- 小狼毫(Rime)输入法设置Shift直接上屏英文字符并切换为英文状态方法
- Script标签解决跨域
- VueSummary_note
- java程序包不存在_idea Error:(3, 32) java: 程序包***不存在的问题
- python 模拟浏览器selenium_Python使用Selenium模块模拟浏览器抓取斗鱼直播间信息示例...
- python fabric上传文件夹_通过python的fabric包完成代码上传部署(简单版)
- jssdk信息验证失败_阿里云环境中TLS/SSL握手失败的场景分析
- react 组件怎么公用_用 react 做一个跟随组件的 tooltip
- Docker安装与卸载,配置阿里云镜像加速器