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 的值 大,那就是递增排序,相反,则 递减排序。


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

猜你喜欢

转载自blog.csdn.net/sw3300255/article/details/84957244
今日推荐