指针基础知识(指针进阶2 – 函数)
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表示函数返回值为空
函数指针数组的应用
#include <stdio.h> 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 <= 0) { printf("退出程序\n"); } else { printf("输入x: "); scanf("%d", &x); printf("输入y: "); scanf("%d", &y); ret = (ptr[input])(x, y); //通过input,锁定函数地址 ,最后传参得到结果 printf("%d\n", ret); } } while (input); }3. 指向函数指针数组的指针
直接看代码
#include <stdio.h> int main() { int arr[10] = { 0 }; // 整形数组 int(*pa)[10] = &arr; // 数组指针 ,指向数组的指针 int(*pf[10])(int, int); // 函数指针数组 int(*(*ppf)[10])(int,int)= &pf // 指向函数指针数组的地址 }既然可以用&操作符取出一个整形数组的地址,那么也可以取出一个函数指针数组的地址
所以 ,指向函数指针数组的指针就是存储整个函数指针数组的地址的变量
int (* (*ppf) [10] ) (int, int) 如何理解 ?
(*ppf), 表示ppf是一个指针, [10]表示这个指针存储一个数组的地址 ,数组有10个元素 ,int (*) (int, int), 表示数组的每一个元素是一个函数指针
创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!