• C语言指针讲解-------进阶篇(下篇)


    目录

    六.函数指针数组

    七.指向函数指针数组的指针

    八.回调函数

    冒泡排序 与 qsort 函数 

    冒泡排序

     qsort函数


    六.函数指针数组

    函数指针数组---数组存放的是函数

                          ---指针存放的是函数的地址

    1. #define _CRT_SECURE_NO_WARNINGS
    2. #include
    3. int Add(int x, int y)
    4. {
    5. return x + y;
    6. }
    7. int Sub(int x, int y)
    8. {
    9. return x - y;
    10. }
    11. int main()
    12. {
    13. int (*pf1)(int, int) = &Add;
    14. int (*pf2)(int, int) = ⋐
    15. int (*pfArr[4])(int, int) = { &Add,&Sub };
    16. //*pfArr存放函数指针的数组
    17. //*pfArr[4]有4个元素,每个元素都是一个函数指针
    18. return 0;
    19. }

    看下面的代码 

    case里面的语句,有好多重复

    就可以利用函数指针数组去让下面的代码变得更简洁

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

    代码改进之后 

    会使多余的代码删除

    在            ret = pfarr[input](x, y);   中如果输入的input 是 1 ----->则进入Add的函数中,将x,y的值传到Add函数中,返回x+y,输入其他数字同理,要注意的是input的值必须(>=1且<=4)

    1. void menu()
    2. {
    3. printf("******************************\n");
    4. printf("*** 1.Add 2.Sub ***\n");
    5. printf("*** 3.Mul 4.Div ***\n");
    6. printf("*** 0.Exit ***\n");
    7. printf("******************************\n");
    8. }
    9. int Add(int x, int y)
    10. {
    11. return x + y;
    12. }
    13. int Sub(int x, int y)
    14. {
    15. return x - y;
    16. }
    17. int Mul(int x, int y)
    18. {
    19. return x * y;
    20. }
    21. int Div(int x, int y)
    22. {
    23. return x / y;
    24. }
    25. int main()
    26. {
    27. int input = 0;
    28. int x = 0;
    29. int y = 0;
    30. int ret = 0;
    31. do
    32. {
    33. menu();
    34. printf("请选择:>");
    35. scanf("%d", &input);
    36. //函数指针数组
    37. int (*pfarr[])(int, int) = { NULL,Add,Sub,Mul,Div };
    38. if (0 == input)
    39. {
    40. printf("退出程序!\n");
    41. }
    42. else if (input >= 1 && input <= 4)
    43. {
    44. printf("请输入2个操作数:");
    45. scanf("%d%d", &x, &y);
    46. ret = pfarr[input](x, y);
    47. printf("ret = %d\n", ret);
    48. }
    49. else
    50. {
    51. printf("选择错误,请重新选择!\n");
    52. }
    53. } while (input);
    54. return 0;
    55. }

    上述代码展示,如下图 

     

    七.指向函数指针数组的指针

    指向函数指针数组的指针是一个指针,指针指向一个数组,数组的元素都是函数指针

    1. int main()
    2. {
    3. int a = 10, b = 20 , c = 30;
    4. int* arr[] = { &a,&b,&c };
    5. //整型指针数组
    6. int* (*p)[3] = &arr;
    7. //p是指针,是指向整形数组的指针
    8. //函数指针数组,存放的是函数的地址
    9. int(*pfArr[5](int, int) = { NULL,Add,Sub,Mul,Div };
    10. //pfArr是函数指针数组
    11. int (*(*p)[5])(int, int) = &Arr;
    12. // *p 是指针,指向数组,有5个元素
    13. // p 就是一个能够指向函数指针数组的指针
    14. }

    向函数指针数组 pfArr 的指针 p 就是一个能够指向函数指针数组的指针

    ( 博主在这里插一嘴,可以继续套娃哦)

    八.回调函数

    回调函数就是一个通过函数指针调用的函数

    如果你把指针(地址)作为参数传给另外一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数

    回调函数不是由该函数的实践方直接调用,而是在特定的事件或条件发生发生时由另外的一方调用的,用于该事件或条件进行响应

    代码演示,用回调函数实现计算器(上面的代码):

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

    冒泡排序 与 qsort 函数 

     

     

    冒泡排序

    代码展示:

    1. void print_arr(int* arr, int sz)
    2. {
    3. int i = 0;
    4. for (i = 0; i < sz; i++)
    5. {
    6. printf("%d ", arr[i]);
    7. }
    8. printf("\n");
    9. }
    10. void bubble_sort(int arr[], int sz)
    11. {
    12. int i = 0;
    13. for (i = 0; i < sz - 1; i++)
    14. {
    15. int j = 0;
    16. for (j = 0; j < sz - 1 - i; j++)
    17. {
    18. if (arr[j] > arr[j + 1])
    19. {
    20. int tmp = arr[j];
    21. arr[j] = arr[j + 1];
    22. arr[j + 1] = tmp;
    23. }
    24. }
    25. }
    26. }
    27. int main()
    28. {
    29. int arr[] = { 9,8,7,6,5,4,3,2,1,0 };
    30. int sz = sizeof(arr) / sizeof(arr[0]);
    31. print_arr(arr, sz);//排序前
    32. bubble_sort(arr, sz);
    33. print_arr(arr, sz);//排序后
    34. return 0;
    35. }

    注意 : 这个函数只能排序整形类型 

     qsort函数
    1. void qsort(void* base, //待排序数组的第一个元素的地址
    2. size_t num, //待排序数组的元素个数
    3. size_t size,//待排序数组中一个元素的大小
    4. int (* cmp)(const void* e1, const void* e2)//函数指针-cmp指向了一个函数,这个函数是用来比较两个元素的
    5. e1和e2中存放的是需要比较的两个元素的地址
    6. );
    7. //1. 排序整型数组, 两个整型可以直接使用>比较
    8. //2. 排序结构体数组,两个结构体的数据可能不能直接使用>比较
    9. 也就是不同类型的数据,比较出大小,方法是有差异的

    qsort() 是 C语言的一个标准库函数,定义在头文件中。

    qsort() 函数用于对数组进行快速排序,它是一个通用的排序函数,支持对不同类型的元素进行排序。

    qsort() 函数的原型如下:

    void qsort (void *base , size_t nitems , size_t size , int (*compar ) ( const void *, const void* ) );

    欲知后事如何,请听下章分解 

     

    新人博主,如果有地方解释的不对或者不清晰,麻烦大佬们海涵,如果可以麻烦从评论区指出,我一定会加以修改,万分感谢

    最后麻烦大佬们动一下发财的小手一键三连,千万分感谢

  • 相关阅读:
    C++ 设计模式 —— 组合模式
    react生命周期新旧对比
    从固定管线到可编程管线:十段代码入门OpenGL
    vue脚手架 笔记01
    配置项目外网访问(公网IP+DDNS)
    自动私信引流软件的运行分享,与开发需要到的技术分析
    TRCX:触摸屏(TSP)分析
    JAVA经典百题之圆的面积
    Docker基本管理
    Halcon Region相关算子(一)
  • 原文地址:https://blog.csdn.net/2201_75886757/article/details/132909079