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

结论是:函数名和&函数名一样 = 函数的地址
什么是函数指针
既然函数名=函数地址,就可以用一个变量进行存储
这个变量就是函数指针,存储一个函数地址的变量 - #include <stdio.h>
- int test(int x, int y)
- {
- ;
- }
- int main()
- {
- int(*ptr)(int, int) = test;
- }
复制代码 这里的ptr就是一个函数指针
(*ptr),表示ptr是一个指针变量 ,(int, int), 表示ptr存储的是一个函数的地址,这个函数有两个int类型的参数,(*ptr)前面的int, 表示这个函数的返回类型为int整形
函数指针的应用
- #include <stdio.h>
- int test(int x, int y)
- {
- return x + y;
- }
- int main()
- {
- int(*ptr)(int, int) = test;
- int ret = (*ptr)(1,2);
- printf("%d\n", ret);
- }
复制代码 
*ptr表示通过地址访问空间 ---> 得到函数的地址 ---> 传值(1,2) ---> 得到结果3 ---> 打印
函数指针作为参数
- // 使用冒泡排序,排序任意类型数组
- #include <string.h>
- #include <stdio.h>
- struct Stu
- {
- char name[10];
- int age;
- };
- int cmp_int(const void* e1, const void* e2)
- {
- return *(int*)e1 - *(int*)e2;
- }
- // 以年龄比较
- int cmp_by_name(const void* e1,const void* e2)
- {
- return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);
- }
- // 以名字比较
- int cmp_by_age(const void* e1, const void* e2)
- {
- return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
- }
- // 交换
- void swap(char* buf1, char* buf2, int width)
- {
- while (width--)
- {
- char tmp = *buf1;
- *buf1 = *buf2;
- *buf2 = tmp;
- buf1++;
- buf2++;
- }
- }
- // 排序
- void bubble_sort(void* base, size_t sz, size_t width, int (*cmp)(const void* e1, const void* e2))
- {
- int i = 0;
- for (i = 0; i < sz - 1; i++)
- {
- int j = 0;
- for (j = 0; j < sz - 1 - i; j++)
- {
- if ((*cmp)( (char*)base+(j*width), (char*)base+((j+1)*width)) > 0)
- {
- swap((char*)base + (j * width), (char*)base + ((j + 1) * width), width);
- }
- }
- }
- }
- //排序整形数组
- void sort_int()
- {
- int arr[10] = { 9,8,7,6,5,4,3,2,1,0 };
- int sz = sizeof(arr) / sizeof(arr[0]);
- bubble_sort(arr, sz, sizeof(arr[0]), cmp_int);
- for (int i = 0; i < 10; i++)
- {
- printf("%d ", arr[i]);
- }
- }
- // 排序结构体数组
- void sort_struct()
- {
- struct Stu t1[5] = { {"c",5 }, { "a",4 }, { "b",3 }, { "e",2 }, { "d",1 } };
- int sz = sizeof(t1) / sizeof(t1[0]);
- bubble_sort(t1, sz, sizeof(t1[0]), cmp_by_name); // 以名字排序
- //bubble_sort(t1, sz, sizeof(t1[0]), cmp_by_age);// 以年龄排序
- }
- int main()
- {
- //sort_int();
- sort_struct();
- }
复制代码
2. 函数指针数组
什么是函数指针数组
首先梳理一下概念,数组是一组相同类型元素的集合,函数指针是存储函数地址的变量
所以函数指针数组,就是存储一组函数地址的集合- #include <stdio.h>
- void test1()
- {
- ;
- }
- void test2()
- {
- ;
- }
- void test3()
- {
- ;
- }
- int main()
- {
- void(*ptr[3])() = { test1,test2,test3 };
- }
复制代码 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 |