• 回调函数和qsort函数


    目录

    1.qsort函数的使用:

    冒泡排序常规写法如下:

    用qsort函数完成冒泡排序:

    用qsort函数排序结构体数据:

     2.bubble_sort函数的改造

    定义:回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个 函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。

    1. #include
    2. void menu()
    3. {
    4. printf("**************************\n");
    5. printf("**** 1.add 2.sub *****\n");
    6. printf("**** 3.mul 4.div *****\n");
    7. printf("**** 0.exit *****\n");
    8. printf("**************************\n");
    9. }
    10. int Add(int x, int y)
    11. {
    12. return x + y;
    13. }
    14. int Sub(int x, int y)
    15. {
    16. return x - y;
    17. }
    18. int Mul(int x, int y)
    19. {
    20. return x * y;
    21. }
    22. int Div(int x, int y)
    23. {
    24. return x / y;
    25. }
    26. void calc(int (*p)(int, int))
    27. {
    28. int x = 0;
    29. int y = 0;
    30. int ret = 0;
    31. printf("请输入两个操作数:>");
    32. scanf("%d %d", &x, &y);
    33. ret = p(x, y);
    34. printf("%d\n", ret);
    35. }
    36. int main()
    37. {
    38. int input = 0;
    39. do
    40. {
    41. menu();
    42. printf("请选择:>");
    43. scanf("%d", &input);
    44. switch (input)
    45. {
    46. case 1:
    47. calc(Add);
    48. break;
    49. case 2:
    50. calc(Sub);
    51. break;
    52. case 3:
    53. calc(Mul);
    54. break;
    55. case 4:
    56. calc(Div);
    57. break;
    58. case 0:
    59. printf("退出计算机\n");
    60. break;
    61. default:
    62. printf("选择错误\n");
    63. break;
    64. }
    65. } while (input);
    66. return 0;
    67. }

    1.qsort函数的使用:

    qsort - C语言标准库提供的排序函数。

    1. // qsort函数 可以排序任意类型的数据
    2. // void qsort( void *base, 用来接收待排数组的起始位置,void*的指针非常宽容,可以接收任意类型的指针
    3. // size_t num, 待排数组的元素个数
    4. // size_t width, 待排数组的元素大小(字节)
    5. // int (*compare )(const void *elem1, const void *elem2 ) );
    6. //比较两个元素大小的函数指针

    冒泡排序常规写法如下:

    缺陷是bubble_sort函数只能排序整型的数据,不能排列其他类型的数据

    1. //bubble_sort函数只能排序整型的数据
    2. void bubble_sort(int arr[], int sz)
    3. {
    4. int i = 0;
    5. //趟数
    6. for (i = 0; i < sz - 1; i++)
    7. {
    8. //一趟冒泡排序的过程
    9. int j = 0;
    10. for (j = 0; j < sz - 1 - i; j++)
    11. {
    12. if (arr[j] > arr[j + 1])
    13. {
    14. int tmp = arr[j];
    15. arr[j] = arr[j + 1];
    16. arr[j + 1] = tmp;
    17. }
    18. }
    19. }
    20. }
    21. void print(int arr[], int sz)
    22. {
    23. int i = 0;
    24. for (i = 0; i < sz; i++)
    25. {
    26. printf("%d ", arr[i]);
    27. }
    28. printf("\n");
    29. }
    30. int main()
    31. {
    32. //冒泡排序
    33. //对整型数据进行排序
    34. int arr[] = { 2,1,3,7,5,9,6,8,0,4 };
    35. int sz = sizeof(arr) / sizeof(arr[0]);
    36. bubble_sort(arr, sz);
    37. print(arr, sz);
    38. return 0;
    39. }

    用qsort函数完成冒泡排序:

    1. #include<stdio.h>
    2. #include<stdlib.h>
    3. void print(int arr[], int sz)
    4. {
    5. int i = 0;
    6. for (i = 0; i < sz; i++)
    7. {
    8. printf("%d ", arr[i]);
    9. }
    10. printf("\n");
    11. }
    12. //int cmp_int(const void* e1, const void* e2)
    13. //{
    14. // if (*(int*)e1 > *(int*)e2)
    15. // return 1;
    16. // else if (*(int*)e1 < *(int*)e2)
    17. // return -1;
    18. // else
    19. // return 0;
    20. //}
    21. int cmp_int(const void* e1, const void* e2)
    22. {
    23. return (*(int*)e1 - *(int*)e2);//升序
    24. //return (*(int*)e2 - *(int*)e1);//降序
    25. }
    26. void test2()
    27. {
    28. int arr[] = { 2,1,3,7,5,9,6,8,0,4 };
    29. int sz = sizeof(arr) / sizeof(arr[0]);
    30. // qsort函数 可以排序任意类型的数据
    31. // void qsort( void *base, 用来接收待排数组的起始位置,void*的指针非常宽容,可以接收任意类型的指针
    32. // size_t num, 待排数组的元素个数
    33. // size_t width, 待排数组的元素大小(字节)
    34. // int (*compare )(const void *elem1, const void *elem2 ) );
    35. //比较两个元素大小的函数指针
    36. qsort(arr, sz, sizeof(arr[0]), cmp_int);
    37. //把cmp_int()函数的指针(地址)作为参数传递给另一个qsort()函数,当指针cmp_int被用来调用其所指向的函数cmp_int()时,我们就说函数cmp_int()是回调函数
    38. print(arr, sz);
    39. }
    40. int main()
    41. {
    42. //test1();
    43. test2();
    44. return 0;
    45. }

    用qsort函数排序结构体数据:

    按照名字排序:

    1. struct Stu
    2. {
    3. char name[20];
    4. int age;
    5. };
    6. void cmp_stu_by_name(const void* e1, const void* e2)
    7. {
    8. return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);
    9. }
    10. //测试去qsort排序结构体数据
    11. void test3()
    12. {
    13. struct Stu s[] = {{"zhangsan", 20}, {"lisi", 55}, {"wangwu",40}};
    14. //假设按照名字比较
    15. int sz = sizeof(s) / sizeof(s[0]);
    16. qsort(s, sz, sizeof(s[0]), cmp_stu_by_name);
    17. }
    18. int main()
    19. {
    20. //test1();
    21. //test2();
    22. test3();
    23. return 0;
    24. }

     按照年龄排序:

    1. struct Stu
    2. {
    3. char name[20];
    4. int age;
    5. };
    6. //按照名字排序
    7. void cmp_stu_by_name(const void* e1, const void* e2)
    8. {
    9. return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);
    10. }
    11. //按照年龄排序
    12. void cmp_stu_by_age(const void* e1, const void* e2)
    13. {
    14. return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
    15. }
    16. //测试去qsort排序结构体数据
    17. void test3()
    18. {
    19. struct Stu s[] = {{"zhangsan", 20}, {"lisi", 55}, {"wangwu",40}};
    20. //假设按照名字比较
    21. int sz = sizeof(s) / sizeof(s[0]);
    22. //qsort(s, sz, sizeof(s[0]), cmp_stu_by_name);按照名字排序
    23. qsort(s, sz, sizeof(s[0]), cmp_stu_by_age);//按照年龄排序
    24. }
    25. int main()
    26. {
    27. //test1();
    28. //test2();
    29. test3();
    30. return 0;
    31. }

     

     2.bubble_sort函数的改造

    把bubble_sort函数改造成qsort函数那样,对于任何类型的数据都可以排序。

    1. int cmp_int(const void* e1, const void* e2)
    2. {
    3. return (*(int*)e1 - *(int*)e2);//升序
    4. //return (*(int*)e2 - *(int*)e1);//降序
    5. }
    6. void print(int arr[], int sz)
    7. {
    8. int i = 0;
    9. for (i = 0; i < sz; i++)
    10. {
    11. printf("%d ", arr[i]);
    12. }
    13. printf("\n");
    14. }
    15. void Swap(char*buf1, char*buf2, int width)
    16. {
    17. int i = 0;
    18. for (i = 0; i < width; i++)
    19. {
    20. char tmp = *buf1;
    21. *buf1 = *buf2;
    22. *buf2 = tmp;
    23. buf1++;
    24. buf2++;
    25. }
    26. }
    27. void bubble_sort2(void* base, int sz, int width, int (*cmp)(const void* e1,const void* e2))
    28. {
    29. int i = 0;
    30. //趟数
    31. for (i = 0; i < sz - 1; i++)
    32. {
    33. //一趟冒泡排序的过程
    34. int j = 0;
    35. for (j = 0; j < sz - 1 - i; j++)
    36. {
    37. if (cmp((char*)base + j * width, (char*)base + (j + 1) * width) > 0)
    38. {
    39. //交换
    40. Swap((char*)base + j * width, (char*)base + (j + 1) * width, width);
    41. }
    42. }
    43. }
    44. }
    45. void test4()
    46. {
    47. int arr[] = { 2,1,3,7,5,9,6,8,0,4 };
    48. int sz = sizeof(arr) / sizeof(arr[0]);
    49. bubble_sort2(arr, sz, sizeof(arr[0]), cmp_int);
    50. print(arr, sz);
    51. }
    52. int main()
    53. {
    54. //test1();
    55. //test2();
    56. //test3();
    57. test4();
    58. return 0;
    59. }
  • 相关阅读:
    等保三级安全要求简要攻略-安全计算环境
    java 常用工具类
    cv2.split函数与cv2.merge函数
    共享充电宝系统架构分析
    selenium学习笔记二
    MySQL详细学习教程(建议收藏)
    使用IE浏览器将pfx转为cer证书
    【C++初阶】动态内存管理
    Linux上后台运行进程(nohub、screen和tmux )
    Windows 下 Qt 可执行程序添加默认管理员权限启动(QMAKE、MinGW & MSVC)
  • 原文地址:https://blog.csdn.net/m0_68071216/article/details/127456909