• 指针进阶全


    个人主页点我进入主页

    专栏分类:C语言初阶      C语言程序设计————KTV       C语言小游戏     C语言进阶

    C语言刷题

    欢迎大家点赞,评论,收藏。

    一起努力,一起奔赴大厂。

    目录

    1.复习

    1.1字符指针

    1.2指针数组

    1.3数组指针

    1.4函数指针

    2.函数指针数组

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

    4.回调函数       


     

            前面写过指针进阶的一部分,没有看过的可以点击指针进阶详解,今天我给大家带来后半部分,以及对于前面内容的一些复习。

    1.复习

    1.1字符指针

    这里我们有创建字符指针,以及利用const修饰字符指针,以及不常用的访问方式,代码如下:

    1. #include
    2. int main()
    3. {
    4. char a = 'w';
    5. char* p = &a;
    6. printf("a = %d\n*p = %d\n", a, *p);
    7. const char* q = "abcde";//由于字符串不可应该,用const
    8. //方便不正当修改字符串时找到错误
    9. char arr[] = "abcdef";
    10. printf("%c", "abcdef"[2]);
    11. return 0;
    12. }

    1.2指针数组

            指针数组也就是存放指针的数组,比如我们想要建立n个链表,链表的类型时struct student类型我们就可以建立为struct student*arr[N]数组的内容就是链表头指针的地址。

    1.3数组指针

            数组指针也就是存放数组的指针,顾名思义他是一个指针*p,我们想要存放整形的数组,也就是返回类型为int,我们可以写为int*p,由于时数组指针,我们需要数组的元素的个数,也就是int(*p)[数组元素的个数]这里加括号的原因是优先级。

    1.4函数指针

            函数指针,就是指向函数的指针,函数也存在地址&函数名和函数名都是函数的地址,例如我们需要指向一个Add函数他的参数为int,int,我们就可以写成int (*p)(int,int),在这里int是函数的返回类型,(int,int)是参数的类型。

    2.函数指针数组

            在前面我们学了函数指针,87函数指针是指针,那么就有函数指针数组,比如我们函数指针的类型为int (*)(int,int), 那么我们函数指针数组的类型也为int (*)(int,int), 故我们可以写为int (*parr[10])(int,int).对于函数指针数组有什么作用,我们可以看一个例子,我们正常写一个计算器,代码如下:

    1. #define _CRT_SECURE_NO_WARNINGS 1
    2. #include
    3. void menu()
    4. {
    5. printf("*********************\n");
    6. printf("***1.加法 2.减法***\n");
    7. printf("***3.乘法 4.除法***\n");
    8. printf("*********************\n");
    9. }
    10. int Add(int x, int y)
    11. {
    12. return x + y;
    13. }
    14. int reduce(int x, int y)
    15. {
    16. return x - y;
    17. }
    18. int ride(int x, int y)
    19. {
    20. return x * y;
    21. }
    22. int div(int x, int y)
    23. {
    24. return x / y;
    25. }
    26. int main()
    27. {
    28. menu();
    29. printf("请输入你想选择运算:");
    30. int num,x,y;
    31. scanf("%d", &num);
    32. printf("请输入两个操作数:");
    33. scanf("%d%d", &x, &y);
    34. switch (num)
    35. {
    36. case 1:
    37. Add(x, y);break;
    38. case 2:
    39. reduce(x, y); break;
    40. case 3:
    41. ride(x, y); break;
    42. case 4:
    43. div(x, y); break;
    44. }
    45. return 0;
    46. }

            我们可以看到如果使用switch的时候比较繁琐,且内容相同,而且各个函数的返回类型和形参类型都相同,故我们可以利用函数指针数组进行操作,代码如下

    1. #include
    2. void menu()
    3. {
    4. printf("*********************\n");
    5. printf("***1.加法 2.减法***\n");
    6. printf("***3.乘法 4.除法***\n");
    7. printf("*********************\n");
    8. }
    9. int Add(int x, int y)
    10. {
    11. return x + y;
    12. }
    13. int reduce(int x, int y)
    14. {
    15. return x - y;
    16. }
    17. int ride(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. menu();
    28. printf("请输入你想选择运算:");
    29. int num,x,y;
    30. scanf("%d", &num);
    31. printf("请输入两个操作数:");
    32. scanf("%d%d", &x, &y);
    33. int(*p[4])(int, int) = { &Add,&reduce,&ride,&div };
    34. if (num >= 1 && num <= 4)
    35. {
    36. int ret = p[num - 1](x,y);
    37. printf("%d", ret);
    38. }
    39. return 0;
    40. }

            我们看到主函数这里简洁了很多,故当函数的返回类型和形参类型相同的时候我们就就可以利用函数指针数组进行操作。

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

            既然函数指针数组是数组,那么就会存在函数指针数组的指针函数指针数组的指针,由于函数指针数组的指针这指针几乎不会用到,我们这里只是介绍,函数指针数组的类型我们可以看函数指针的类型,比如返回类型为int,参数为int,int,函数指针的类型为int(*)(int,int),那么函数指针数组的类型为int(*)(int,int),故指向函数指针数组的指针类型为int(*)(int,int),故我们可以写为int(*(*p)[10])(int,int)。

    4.回调函数       

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

    1. #include
    2. void menu()
    3. {
    4. printf("*********************\n");
    5. printf("***1.加法 2.减法***\n");
    6. printf("***3.乘法 4.除法***\n");
    7. printf("*********************\n");
    8. }
    9. int Add(int x, int y)
    10. {
    11. return x + y;
    12. }
    13. int reduce(int x, int y)
    14. {
    15. return x - y;
    16. }
    17. int ride(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 cacl(int(*p)(int,int))
    26. {
    27. int x, y;
    28. printf("请输入两个操作数:");
    29. scanf("%d%d", &x, &y);
    30. int ret = p(x, y);
    31. }
    32. int main()
    33. {
    34. menu();
    35. printf("请输入你想选择运算:");
    36. int num;
    37. scanf("%d", &num);
    38. switch (num)
    39. {
    40. case 1:
    41. cacl(&Add); break;
    42. case 2:
    43. cacl(&reduce); break;
    44. case 3:
    45. cacl(&ride); break;
    46. case 4:
    47. cacl(&div); break;
    48. }
    49. return 0;
    50. }

    今天的内容就结束了,希望大家可以一键三连;

     

  • 相关阅读:
    实现线程池
    MySQL 是什么有什么用处下载和安装教程等值连接数据库基础知识怎么读取增删改短语优化的几种方法
    前端项目通过‘URL 重写’部署在 IIS 中,访问 WebAPI 接口
    HTML5-框架-计算机应用2115-2022年11月17日13:57:13
    Git 冲突处理指南:恢复 Git Reset
    Android热修复2(ASM技术的运用)
    3C认证所需要的条件和流程
    《痞子衡嵌入式半月刊》 第 57 期
    Python编程 字典创建map与Zip
    第22章_瑞萨MCU零基础入门系列教程之DMA控制器
  • 原文地址:https://blog.csdn.net/Infernal_Puppet/article/details/132824585