• 指针传2(续集)


    近期的天气是真的冷啊,老铁们一定要照顾好自己呀,注意防寒保暖,没有你们我怎么活啊!

    上次的指针2的末尾,给大家分享了两个有趣的代码,今天就先来讲一讲那两个代码:

    两个有趣的代码:

    1  ( *  (   void  (*)    (  )   )   ) ( ); 
    相同颜色的就是对应的一对括号,我们从里面看着出来,void  (*)  (  )这是一种指针类型吧,然后就是(   void  (*)    (  )   )   表示将0地址强制转换为函数指针类型,像我们之前写的(int)3.14这中就是强制类型转换,之后还剩下(*)(),这个不就是函数的调用吗?所以这是一次函数调用,将整数值0强制类型转换成一个函数地址,这个函数没有参数,返回类型为void;
    去调用0地址处的函数.
    void (*signal (int , void(*)(int) ) ) (int );
    我们还是从里面分析着出来,首先看 signal (int , void(*)(int),这不就是一个函数吗?里面有两个参数,第一个是int类型,第二个是函数指针类型,该指针指向的函数参数是int,返回类型是void,signal函数的返回类型是这种类型的void(*)(int)函数指针,该指针指向的函数参数是int,返回类型是void,这是函数的声明!

    函数指针数组:

    函数指针数组是一个数组,其元素都是指向函数的指针。它的定义形式如下:

    返回类型 (*指针数组名称[元素个数])(参数1类型, 参数2类型, ...);


    其中,返回类型是函数的返回类型,指针数组名称是一个合法的标识符,元素个数是指针数组中元素的个数。参数类型是函数的参数类型。

    例如,定义一个包含3个元素的函数指针数组,每个元素都指向返回类型为int,参数类型为int的函数,可以如下定义:
    int (* PArray[3] )  (int);

    PArray先和 [] 结合,说明 PArray是数组,数组的内容是 int (*)(int) 类型的函数指针。

    这样,PArray就是一个包含3个元素的函数指针数组,每个元素都是指向返回类型为int,参数类型为int的函数的指针。

    函数指针数组的使用:
    我们编写计算器的实现:
    先看看第一种方法:
    1. #define _CRT_SECURE_NO_WARNINGS 1
    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 Mul(int x, int y)
    12. {
    13. return x * y;
    14. }
    15. int Div(int x, int y)
    16. {
    17. return x / y;
    18. }
    19. void mune(void)
    20. {
    21. printf("************************\n");
    22. printf("*****1,加法运算 ********\n");
    23. printf("*****2,减法运算 ********\n");
    24. printf("*****3,乘法运算 ********\n");
    25. printf("*****4,除法运算 ********\n");
    26. printf("*****0,退出计算 ********\n");
    27. printf("************************\n");
    28. }
    29. int main()
    30. {
    31. int input = 0;
    32. int x = 0;
    33. int y = 0;
    34. int ret = 0;
    35. do
    36. {
    37. mune();
    38. printf("请选择:\n");
    39. scanf("%d", &input);
    40. switch (input)
    41. {
    42. case 1:
    43. printf("请输入两个操作数:\n");
    44. scanf("%d %d", &x, &y);
    45. ret = Add(x, y);
    46. printf("%d\n", ret);
    47. break;
    48. case 2:
    49. printf("请输入两个操作数:\n");
    50. scanf("%d %d", &x, &y);
    51. ret = Sub(x, y);
    52. printf("%d\n", ret);
    53. break;
    54. case 3:
    55. printf("请输入两个操作数:\n");
    56. scanf("%d %d", &x, &y);
    57. ret = Mul(x, y);
    58. printf("%d\n", ret);
    59. break;
    60. case 4:
    61. printf("请输入两个操作数:\n");
    62. scanf("%d %d", &x, &y);
    63. ret = Div(x, y);
    64. printf("%d\n", ret);
    65. break;
    66. case 0:
    67. printf("退出计算器\n");
    68. break;
    69. default:
    70. printf("输入错误,请重新输入!\n");
    71. break;
    72. }
    73. } while (input);
    74. return 0;
    75. }

    这种方法相信大家都会的吧,就是我们前面知识的应用,就不和大家细说了。上面我们看见重复的代码太多了,而且我们以后想实现其他的运算就会变得很麻烦。


    上述的方法,我们可不可以把它们进行封装到另一个函数里面呢,通过函数指针找到相应的函数:

    1. #define _CRT_SECURE_NO_WARNINGS 1
    2. #include
    3. int input = 0;
    4. int x = 0;
    5. int y = 0;
    6. int ret = 0;
    7. int Add(int x, int y)
    8. {
    9. return x + y;
    10. }
    11. int Sub(int x, int y)
    12. {
    13. return x - y;
    14. }
    15. int Mul(int x, int y)
    16. {
    17. return x * y;
    18. }
    19. int Div(int x, int y)
    20. {
    21. return x / y;
    22. }
    23. void mune(void)
    24. {
    25. printf("************************\n");
    26. printf("*****1,加法运算 ********\n");
    27. printf("*****2,减法运算 ********\n");
    28. printf("*****3,乘法运算 ********\n");
    29. printf("*****4,除法运算 ********\n");
    30. printf("*****0,退出计算 ********\n");
    31. printf("************************\n");
    32. }
    33. void calc( int(*pf)(int, int))//函数指针
    34. {
    35. printf("请输入两个操作数:\n");
    36. scanf("%d %d", &x, &y);
    37. ret = pf(x, y);
    38. printf("%d\n", ret);
    39. }
    40. int main()
    41. {
    42. do
    43. {
    44. mune();
    45. printf("请选择:\n");
    46. scanf("%d", &input);
    47. switch (input)
    48. {
    49. 回调函数就是⼀个通过函数指针调⽤的函数。
    50. case 1:
    51. calc(Add);
    52. break;
    53. case 2:
    54. calc(Sub);
    55. break;
    56. case 3:
    57. calc(Mul);
    58. break;
    59. case 4:
    60. calc(Div);
    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. }

    我们来看看运行效果:


    我们可不可以把这些函数放在一个数组里面呢,因为这些函数都是这一大类的吧,弄一个函数指针数组,然后根据输入去调用相应的函数:

    int (*parr[5]) (int, int) = { NULL,Add,Sub,Mul,Div };

    前面加上一个空指针,这样我们在输入数字的时候就可以找到相应的函数(数组的下标是从0开始的)!

    1. int main()
    2. {
    3. int input = 0;
    4. int x = 0;
    5. int y = 0;
    6. int ret = 0;
    7. do
    8. {
    9. mune();
    10. printf("请选择:\n");
    11. scanf("%d", &input);
    12. int (*parr[5]) (int, int) = { NULL,Add,Sub,Mul,Div };
    13. //这里的函数指针数组我们称为转移表
    14. if (input == 0)
    15. {
    16. printf("退出计算器\n");
    17. }
    18. else if(input>=1 && input<=4)
    19. {
    20. printf("请输入两个操作数:\n");
    21. scanf("%d %d", &x, &y);
    22. ret = parr[input](x, y);
    23. printf("%d\n", ret);
    24. }
    25. else
    26. {
    27. printf("输入错误,请重新输入!\n");
    28. }
    29. } while (input);
    30. return 0;
    31. }

    这样我们是不是就大大减少了我们的代码量了,而且如果想加上其他的方法,加在数组里面就可以了,但这只是其中一部分代码哈,前面的方法我没有写上。

    好了,今天就到这里了,明天见哦,不要太想我哟!😊😊😊


     

  • 相关阅读:
    Linux命令行及图形化窗口安装与切换
    布线前,布局这步极为关键!分享一些PCB设计布线注意要点
    B模块数据库安全加固
    Java并发编程图册
    使用Xposed对软件进行破解
    【实用 Python 库】使用 XPath 与 lxml 模块在 Python 中高效解析 XML 与 HTML
    Python 基础语法
    Opengauss到Oracle增量同步, 使用debezium
    tolua源码分析(六) C#委托使用lua函数的机制实现
    Visual Studio 和 VSCode 哪个好?
  • 原文地址:https://blog.csdn.net/2302_77675796/article/details/134470749