指针进阶2 - 函数

[复制链接]
发表于 2023-2-20 13:07:55 | 显示全部楼层 |阅读模式
1. 函数指针

函数名 VS &函数名

对于数组而言,数组名=首元素地址,&数组名=整个数组的地址
那么函数名和&函数名等于什么
  1. #include <stdio.h>
  2. void test()
  3. {
  4.         ;
  5. }
  6. int main()
  7. {
  8.         test();
  9.         printf("%p\n", test);
  10.         printf("%p\n", &test);
  11. }
复制代码
注:函数名和&函数名不能+-整数

结论是:函数名和&函数名一样 = 函数的地址
 
什么是函数指针

既然函数名=函数地址,就可以用一个变量进行存储
这个变量就是函数指针,存储一个函数地址的变量 
  1. #include <stdio.h>
  2. int test(int x, int y)
  3. {
  4.         ;
  5. }
  6. int main()
  7. {
  8.         int(*ptr)(int, int) = test;
  9. }
复制代码
这里的ptr就是一个函数指针
(*ptr),表示ptr是一个指针变量 ,(int, int), 表示ptr存储的是一个函数的地址,这个函数有两个int类型的参数,(*ptr)前面的int, 表示这个函数的返回类型为int整形
 
函数指针的应用
  1. #include <stdio.h>
  2. int test(int x, int y)
  3. {
  4.         return x + y;
  5. }
  6. int main()
  7. {
  8.         int(*ptr)(int, int) = test;
  9.         int ret = (*ptr)(1,2);
  10.         printf("%d\n", ret);
  11. }
复制代码
 
*ptr表示通过地址访问空间 ---> 得到函数的地址 ---> 传值(1,2) ---> 得到结果3 ---> 打印
 
函数指针作为参数
  1. // 使用冒泡排序,排序任意类型数组
  2. #include <string.h>
  3. #include <stdio.h>
  4. struct Stu
  5. {
  6.         char name[10];
  7.         int age;
  8. };
  9. int cmp_int(const void* e1, const void* e2)
  10. {
  11.         return *(int*)e1 - *(int*)e2;
  12. }
  13. // 以年龄比较
  14. int cmp_by_name(const void* e1,const void* e2)
  15. {
  16.         return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);
  17. }
  18. // 以名字比较
  19. int cmp_by_age(const void* e1, const void* e2)
  20. {
  21.         return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
  22. }
  23. // 交换
  24. void swap(char* buf1, char* buf2, int width)
  25. {
  26.         while (width--)
  27.         {
  28.                 char tmp = *buf1;
  29.                 *buf1 = *buf2;
  30.                 *buf2 = tmp;
  31.                 buf1++;
  32.                 buf2++;
  33.         }
  34. }
  35. // 排序
  36. void bubble_sort(void* base, size_t sz, size_t width, int (*cmp)(const void* e1, const void* e2))
  37. {
  38.         int i = 0;
  39.         for (i = 0; i < sz - 1; i++)
  40.         {
  41.                 int j = 0;
  42.                 for (j = 0; j < sz - 1 - i; j++)
  43.                 {
  44.                         if ((*cmp)( (char*)base+(j*width), (char*)base+((j+1)*width)) > 0)
  45.                         {
  46.                                 swap((char*)base + (j * width), (char*)base + ((j + 1) * width), width);
  47.                         }
  48.                 }
  49.         }
  50. }
  51. //排序整形数组
  52. void sort_int()
  53. {
  54.         int arr[10] = { 9,8,7,6,5,4,3,2,1,0 };
  55.         int sz = sizeof(arr) / sizeof(arr[0]);
  56.         bubble_sort(arr, sz, sizeof(arr[0]), cmp_int);
  57.         for (int i = 0; i < 10; i++)
  58.         {
  59.                 printf("%d ", arr[i]);
  60.         }
  61. }
  62. // 排序结构体数组
  63. void sort_struct()
  64. {
  65.         struct Stu t1[5] = { {"c",5 }, { "a",4 }, { "b",3 }, { "e",2 }, { "d",1 } };
  66.         int sz = sizeof(t1) / sizeof(t1[0]);
  67.         bubble_sort(t1, sz, sizeof(t1[0]), cmp_by_name); // 以名字排序
  68.         //bubble_sort(t1, sz, sizeof(t1[0]), cmp_by_age);// 以年龄排序
  69. }
  70. int main()
  71. {
  72.         //sort_int();
  73.         sort_struct();
  74. }
复制代码
 
2. 函数指针数组

什么是函数指针数组

首先梳理一下概念,数组是一组相同类型元素的集合,函数指针是存储函数地址的变量
所以函数指针数组,就是存储一组函数地址的集合
  1. #include <stdio.h>
  2. void test1()
  3. {
  4.         ;
  5. }
  6. void test2()
  7. {
  8.         ;
  9. }
  10. void test3()
  11. {
  12.         ;
  13. }
  14. int main()
  15. {
  16.         void(*ptr[3])() = { test1,test2,test3 };
  17. }
复制代码
void (* ptr[3] )() , 如何理解 ?
ptr首先会与[3]结合,表示ptr是一个数组,数组有3个元素
void (* ptr[3] )() ---> void (*)(),
(*) 表示数组的每一个元素是一个指针,()表示这个指针是一个函数指针且函数没有参数,void表示函数返回值为空
 
函数指针数组的应用

[code]#include int add(int x, int y){        return x + y;}int sub(int x, int y){        return x - y;}int mul(int x, int y){        return x * y;}int div(int x, int y){        return x / y;}void menu(){        printf("1.add        2.sub\n");        printf("3.mul        4.div\n");}int main(){        int(*ptr[5])(int, int) = { 0,add,sub,mul,div }; //函数指针数组        int input = 0;        int x = 0;        int y = 0;        int ret = 0;        do         {                menu();                printf("输入: ");                scanf("%d", &input);                if (input > 4 || input

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表