函数指针的用法
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 的值 大,那就是递增排序,相反,则 递减排序。
有编过程的人的代码,比那些无知的人使用的软件更有价值。