当前位置:   article > 正文

C语言指针深造及回调函数总结_c语言指针回调

c语言指针回调

 一、数组指针

      概述:数组指针是指针,简单来说数组可以当做修饰语,修饰指针,只不过它是一个指向数组的指针。

      举例:int *p[100];表示指针数组https://blog.csdn.net/Sun_student/article/details/83932242)这里有指针数组的概念,

                 int (*p)[100];表示数组指针,指向int型数组的指针。

                 帮助理解:*符号的优先级比[ ]符号的优先级低,所以表示数组指针的时候记得给指针加()。

      怎么使用数组指针?

             数组指针是指向数组的指针,那么它就存储的是数组的地址。

             举例:          

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. void print_arr1(int arr[3][5], int row, int col)
  4. {
  5. int i = 0;
  6. int j = 0;
  7. for(i=0; i<row; i++)
  8. {
  9. for(j=0; j<col; j++)
  10. {
  11. printf("%d ", arr[i][j]);
  12. }
  13. printf("\n");
  14. }
  15. }
  16. void print_arr2(int (*arr)[5], int row, int col)
  17. {
  18. int i = 0;
  19. int j = 0;
  20. for (i = 0; i<row; i++)
  21. {
  22. for (j = 0; j<col; j++)
  23. {
  24. printf("%d ", arr[i][j]);
  25. }
  26. printf("\n");
  27. }
  28. }
  29. int main()
  30. {
  31. int arr[3][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
  32. print_arr1(arr, 3, 5);
  33. printf("-----------\n");
  34. //数组名arr,表示首元素的地址    
  35. //但是二维数组的首元素是二维数组的第一行    
  36. //所以这里传递的arr,其实相当于第一行的地址,是一维数组的地址    
  37. //可以数组指针来接收    
  38. print_arr2(arr, 3, 5);
  39. system("pause");
  40. return 0;
  41. }

        从代码中可以看出int arr[3][5]等价于int (*arr)[5],传递的参数是一个二维数组,二维数组的第一个元素相当于一个一位数组,那么接受这个一位数组的地址就可以使用一个数组指针来接收。

        注意:二维数组传递参数,第二个[ ]里必须声明参数的值,不然编译器不知道二维数组里每一个一位数组值的个数是多少,会报错。

二、函数指针

      简单概述:函数也有地址,那么就可以通过指针进行解引用,即就是函数指针。

      其实函数指针不经常使用,但是我们还是要理解函数指针,看两个代码:

              1.(*(void (*)())0)();    2.void (*signal(int, void(*)(int)))(int);

      理解思路:小编个人喜欢从里往外分析,也可以从外往里分析。

              1.先看(*)()表示一个函数指针,定义一个*p指针变量,这里小编假设默认p的初始化为0(这里的代价就是多声明了一个“哑”变量),所以(*0)()可以表示为(*)();再来看void (*)()表示返回值为void型的指针类型;再分析(void (*)())0 :0表示量,对常量前面加类型表示强制类型转换,那么就可以定义一个变量fp,令fp表示(void (*)())0 ;最后(*(void (*)())0)()表示(*fp)(),这不就是一个函数指针么。所以(*(void (*)())0)()表示一个函数指针,只不过这个函数指针是一个返回值为void的函数的指针类型。

              2.先来了解signal函数:函数中第一个参数是一个整型的信号编号,第二个参数是一个指向调用前的用户定义信号处理函数的指针;这个小编采用从外往里分析:void函数,void函数里面是一个signal函数,只不过这个函数的返回值是一个指针类型,所以void (*signal(int, void(*)(int)))(int)是函数指针,只不过这个函数指针是一个void型,返回值为指针类型。

三、函数指针数组

      简单概述:简单来说就是一个数组,只不过每个元素都是一个函数指针的地址,通过对地址的解引用来调用数组里面的函数。

      用途:转移表,举例:

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include<stdio.h>
  3. #include<stdlib.h>
  4. int add(int a, int b)
  5. {
  6. return a + b;
  7. }
  8. int sub(int a, int b)
  9. {
  10. return a - b;
  11. }
  12. int mul(int a, int b)
  13. {
  14. return a*b;
  15. }
  16. int dvi(int a, int b)
  17. {
  18. return a / b;
  19. }
  20. int main()
  21. {
  22. int x, y;
  23. int input = 1;
  24. int ret = 0;
  25. int (*p[5])(int x, int y) = { 0, add, sub, mul, dvi };//转移表
  26. while (input)
  27. {
  28. printf("==================\n");
  29. printf(" 1:add 2:sub \n");
  30. printf(" 3.mul 4:div \n");
  31. printf("==================\n");
  32. printf("请输入:");
  33. scanf("%d", &input);
  34. if ((input <= 4) && (input >= 1))
  35. {
  36. printf("请输入操作数:");
  37. scanf("%d %d", &x, &y);
  38. ret = (*p[input])(x, y);
  39. }
  40. else
  41. {
  42. printf("输入有误\n");
  43. }
  44. printf("ret = %d\n", ret);
  45. }
  46. system("pause");
  47. return 0;
  48. }

       强调:函数名的地址就是函数所在的首地址。

四、指向函数指针数组的指针

     简单概述:很明显是一个指针,只不过是一个指向函数指针的数组,数组里面的元素为函数指针。

     那怎么定义一个这样的指针:先定义一个函数指针void(*pfun)(),根据函数指针再用定一个函数指针数组void(*pfunarr[100])(),从而表示出void(*(*ppfunarr)[100])(),那么ppfunarr就是一个指向函数指针数组pfunarr的指针。

五、回调函数

                      

     根据上图分析:qsort是实现排序的函数,其中有四个变量:1.数组;2.数组的元素个数;3.数组类型的大小;4.比较函数。

六、练习题

      指针:1.例题

                         

                  代码实现:

                      

                  2.例题

                        

                   代码实现:

                       

      qsort的各类型排序:

              1.char整型代码:

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. //实现qsort的整型排序
  4. int int_cmp(const void* p1, const void* p2)
  5. {
  6. return (*(char*)p1 - *(char*)p2);
  7. }
  8. int main()
  9. {
  10. char arr[] = { 'a', 'd', 'c', 'b', 'e' };
  11. int len = sizeof(arr) / sizeof(arr[0]);
  12. qsort(arr, len, sizeof(char), char_cmp);
  13. for (int i = 0; i < len; ++i)
  14. {
  15. printf("%c", arr[i]);
  16. }
  17. printf("\n");
  18. system("pause");
  19. return 0;
  20. }

              2.int字符型:

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. //实现qsort的整型排序
  4. int int_cmp(const void* p1, const void* p2)
  5. {
  6. return (*(int*)p1 - *(int*)p2);
  7. }
  8. int main()
  9. {
  10. int arr[] = { 5, 3, 2, 0, 4, 6, 8, 9, 7, 1 };
  11. int len = sizeof(arr) / sizeof(arr[0]);
  12. qsort(arr, len, sizeof(int), int_cmp);
  13. for (int i = 0; i < len; ++i)
  14. {
  15. printf("%d", arr[i]);
  16. }
  17. printf("\n");
  18. system("pause");
  19. return 0;
  20. }

      模仿qsort实现一个通用的冒泡排序:

            代码实现:

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. //使用qsort模拟实现一个通用的冒泡排序
  4. int cmp(const void* p1, const void* p2)
  5. {
  6. return (*(int*)p1 - *(int*)p2);
  7. }
  8. void Bubble(int* arr, int len)
  9. {
  10. int count = len;
  11. while (count != 1)
  12. {
  13. for (int i = 0; i < len - 1; ++i)
  14. {
  15. if (cmp(&arr[i], &arr[i+1]) < 0)
  16. {
  17. int tmp = arr[i];
  18. arr[i] = arr[i + 1];
  19. arr[i + 1] = tmp;
  20. }
  21. }
  22. --count;
  23. }
  24. for (int i = 0; i < len; ++i)
  25. {
  26. printf("%d ", arr[i]);
  27. }
  28. printf("\n");
  29. }
  30. int main()
  31. {
  32. int arr[] = { 5, 0, 2 };
  33. int len = sizeof(arr) / sizeof(arr[0]);
  34. Bubble(arr, len);
  35. system("pause");
  36. return 0;
  37. }

             

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/175826
推荐阅读
相关标签
  

闽ICP备14008679号