C语言中的回调函数 和 函数指针

文章介绍了如何通过添加函数指针作为参数来实现冒泡排序的灵活性,使得排序既可以从小到大也可以从大到小,无需重写排序函数。示例代码展示了如何使用greater和less两个函数进行比较,以及如何在sort2函数中调用这些函数指针来改变排序方向。

以冒泡排序为例:

void sort(int *a, int size)
{
    int i, j;
    for (i = 0; i < size-1; i++)
    {
        for (j = 0; j < size - i - 1; j++)
        {
            if (a[j] > a[j+1])
            {
                int num = a[j];
                a[j] = a[j+1];
                a[j+1] = num;
            }
            
        }
        
    }
    
}

int main(){

    int arr[9] = {1,2,3,4,5,6,7,8,9};

    sort(arr, 9); // sort
    for (int i = 0; i < 9; i++)
    {
        printf("%d ", arr[i]);
    }
    
    return 0;
}

结果

在这里插入图片描述
但冒泡排序只能实现从小到大排序,如果想实现从大到小排序,难道就要重写sort函数了吗

可以用函数指针 作为回调函数传入,避免修改函数的麻烦
定义以下函数

int greater(int a, int b)
{
    return a < b ? 1 : 0;
}

int less(int a, int b)
{
    return a > b ? 1 : 0;
}

void sort2(int *a, int size, int (*p)(int,int))
{
    int i, j;
    for (i = 0; i < size-1; i++)
    {
        for (j = 0; j < size - i - 1; j++)
        {
            if (p(a[j], a[j+1]))
            {
                int num = a[j];
                a[j] = a[j+1];
                a[j+1] = num;
            }
            
        }
        
    }
    
}

sort2中添加了函数指针 int (*p)(int,int), 且函数比较由

a[j] > a[j+1]

变为了

(p(a[j], a[j+1])

此时,main函数为

int main(){

    int arr[9] = {1,2,3,4,5,6,7,8,9};

    //sort(arr, 9); // sort
    sort2(arr, 9, greater);
    for (int i = 0; i < 9; i++)
    {
        printf("%d ", arr[i]);
    }
    printf("\r\n");

    sort2(arr, 9, less);

    for (int i = 0; i < 9; i++)
    {
        printf("%d ", arr[i]);
    }
    return 0;
}

结果:
在这里插入图片描述
没有修改sort函数 就实现了冒泡排序的逆序

一个看复杂指针的技巧:

例如

int *(*(*fp)(int))[10];

右左法则
先向右分析 再向左分析

找到变量名fp 向右看 是个右括号,向左看,是个*号,说明fp是个指针。再分析fp指向什么。

c 语言中,括号除了表示优先级,还可以作位函数调用运算符。所以fp是个指针,指向函数。函数需要分析参数和返回值类型。
fp右侧是个函数,函数的参数只有一个,类型为int。

(int)

再向左看 函数的返回值是

(*

是个指针

这个指针指向什么? 继续先向右看 指向了一个数组

[10]

再看左边 剩下了 int*
表示数组中每个元素都是整型指针

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

潘诺西亚的火山

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值