美文网首页
[习题18]C语言 回调函数: test_sorting( ..

[习题18]C语言 回调函数: test_sorting( ..

作者: AkuRinbu | 来源:发表于2018-10-14 15:24 被阅读12次

使用教材

《“笨办法” 学C语言(Learn C The Hard Way)》
https://www.jianshu.com/p/b0631208a794

附加任务

[习题18]回调函数:指向函数的指针 int (*POINTER_NAME) = (int a ,int b);
https://www.jianshu.com/p/a63b9575c86a
" 再写一个排序算法,并修改 test_sorting,让它可以接受任意排序函数以及排序函数的回调比较,用它来测试你的两个算法。"

  • 附加任务说白了,就是想要可以用 test_sorting( ..., ... , 排序函数, 排序规则),也就是可以在main里面直接自由指定想要测试的排序函数以及排序规则

排序算法

  • 插入排序,图片取自WIKI,会动的,很形象;
Insertion-sort-example-300px.gif
https://en.wikipedia.org/wiki/Insertion_sort
  • 代码参考

https://algs4.cs.princeton.edu/21elementary/Insertion.java.html

调试运行

$ make ex18_a
clang -Wall -g    ex18_a.c   -o ex18_a
$ ./ex18_a 4 1 7 3 2 0 8
Bubble_sort:
0 1 2 3 7 4 8 
8 7 4 3 2 0 1 
8 2 3 7 4 0 1 
Insert_sort:
0 1 2 3 4 7 8 
8 7 4 3 2 1 0 
4 1 7 3 2 0 8 

代码说明

1、 新增类型

  • typedef int*(*sort_cb)(int* numbers, int count, compare_cb cmp);

2、修改函数 void test_sorting

  • void test_sorting(int *numbers, int count, compare_cb cmp, sort_cb sort) {}
  • 增加了第四个参数sort_cb sort
  • 函数内部调用排序函数时写 int *sorted = sort(numbers, count, cmp);
    等价于 int *sorted = bubble_sort(numbers, count, cmp);
    等价于 int *sorted = insert_sort(numbers, count, cmp);
    代码运行时,具体是bubble_sort还是insert_sort,视main函数里的调用语句而定;

3、新增函数 插入排序 int *insert_sort

  • 与冒泡的实现相比,函数结构其实几乎一致;

4、主函数调用

    printf("Bubble_sort:\n");
    test_sorting(numbers, count, sorted_order , bubble_sort);
    test_sorting(numbers, count, reverse_order, bubble_sort);
    test_sorting(numbers, count, strange_order, bubble_sort);
    
    printf("Insert_sort:\n");
    test_sorting(numbers, count, sorted_order , insert_sort);
    test_sorting(numbers, count, reverse_order, insert_sort);
    test_sorting(numbers, count, strange_order, insert_sort);
  • { 从小到大,从大到小,乱七八糟 } x { 冒泡,插入}3 * 2 = 6种组合;

5、附加任务的意义

  • 如果以后增加了新的排序算法,比如选择排序、快速排序、希尔排序,归并排序等等,只要函数的接口满足typedef int*(*sort_cb)(int* numbers, int count, compare_cb cmp);,也就是传入这三个指定类型的参数,再返回的是一个int型指针,那就不必再修改test_sorting,直接在main里面写用例进行测试即可;

完整源码

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

/* Our old friend die from ex17. */
void die(const char *message)
{
    if(errno) {
        perror(message);
    } else {
        printf("ERROR: %s\n", message);
    }
    
    exit(1);
}

// a typedef creates a fake type, in this
// case for a funciton pointer
typedef int(*compare_cb)(int a, int b);
typedef int*(*sort_cb)(int* numbers, int count, compare_cb cmp);


/**
*   A classic bubble sort function that uses the 
*   compare_cb to do the sorting.
*/
int *bubble_sort(int *numbers, int count, compare_cb cmp)
{
    int temp = 0;
    int i = 0;
    int j = 0;
    int *target = malloc(count * sizeof(int));
    
    if(!target) 
        die("Memory error.");
    
    memcpy(target, numbers, count * sizeof(int));
    
    for(i = 0 ; i < count; i++) {
        for(j = i+1 ; j < count-1; j++) {
            if(cmp(target[i], target[j+1]) > 0) {
                temp = target[j+1];
                target[j+1] = target[i];
                target[i] = temp;
            }
        }
    }
    
    return target;
}


int *insert_sort(int *numbers, int count, compare_cb cmp)
{
    int temp = 0;
    int i = 0;
    int j = 0;
    int *target = malloc(count * sizeof(int));
    if(!target) 
        die("Memory error.");
    
    memcpy(target, numbers, count * sizeof(int));
    
    for(i = 1; i < count; i++) {
        for(j = i; j > 0; j--) {
            if(cmp(target[j], target[j-1]) < 0) {
                temp = target[j-1];
                target[j-1] = target[j];
                target[j] = temp;
            }
        }
    }
    
    return target;
}


int sorted_order(int a, int b)
{
    return a - b;
}

int reverse_order(int a, int b) 
{
    return b - a;
}

int strange_order(int a, int b) 
{
    if(a == 0 || b == 0) {
        return 0;
    } else {
        return a % b;
    }
}

/**
*   Used to test that we are sorting things correctly
*   by doing the sort and printing it out.
*/
void test_sorting(int *numbers, int count, compare_cb cmp, sort_cb sort) 
{
    int i = 0;
    int *sorted = sort(numbers, count, cmp);
    
    if(!sorted)
        die("Failed to sort as requested.");
    
    for(i = 0; i < count; i++) {
        printf("%d ", sorted[i]);
    }
    printf("\n");
    
    free(sorted);
}

int main(int argc, char *argv[])
{
    if(argc < 2) die("USAGE: ex18 4 3 1 5 6");
    
    int count = argc - 1;
    int i = 0;
    char **inputs = argv + 1;
    
    int *numbers = malloc(count * sizeof(int));
    if(!numbers) die("Memory error.");
    
    for(i = 0 ; i < count; i++) {
        numbers[i] = atoi(inputs[i]);
    }
    
    printf("Bubble_sort:\n");
    test_sorting(numbers, count, sorted_order , bubble_sort);
    test_sorting(numbers, count, reverse_order, bubble_sort);
    test_sorting(numbers, count, strange_order, bubble_sort);
    
    printf("Insert_sort:\n");
    test_sorting(numbers, count, sorted_order , insert_sort);
    test_sorting(numbers, count, reverse_order, insert_sort);
    test_sorting(numbers, count, strange_order, insert_sort);
    
    
    free(numbers);
    
    return 0;
}

相关文章

网友评论

      本文标题:[习题18]C语言 回调函数: test_sorting( ..

      本文链接:https://www.haomeiwen.com/subject/qppaaftx.html