详解函数指针(●‘◡‘●)☞

本文紧接于http://t.csdn.cn/78wbF 这篇

一.函数指针数组\ ( >O< ) /

1.书写形式:由函数指针内部*+变量名==>*+变量名+[n];

2.使用:函数指针数组的用途:转移表

例如:模拟计算器:

#include<stdio.h>
int add(int a, int b)
{
    return a + b;
}
int sub(int a, int b)
{
    return a - b;
}
int mul(int a, int b)
{
    return a * b;
}
int div(int a, int b)
{
    return a / b;
}
int main()
{
        int x, y;
        int input = 1;
        int ret = 0;
        do
        {
            printf("*************************\n");
            printf("      1:add 2:sub        \n");
            printf("      3:mul 4:div        \n");
            printf("*************************\n");
            printf("请选择:");
            scanf("%d", &input);
            switch (input)
            {
            case 1:
                printf("输入操作数:");
                scanf("%d %d", &x, &y);
                ret = add(x, y);
                printf("ret = %d\n", ret);
                break;
            case 2:
                printf("输入操作数:");
                scanf("%d %d", &x, &y);
                ret = sub(x, y);
                printf("ret = %d\n", ret);
                break;
            case 3:
                printf("输入操作数:");
                scanf("%d %d", &x, &y);
                ret = mul(x, y);
                printf("ret = %d\n", ret);
                break;
            case 4:
                printf("输入操作数:");
                scanf("%d %d", &x, &y);
                ret = div(x, y);
                printf("ret = %d\n", ret);
                break;
            case 0:
                printf("退出程序\n");
                break;
            default:
                printf("选择错误\n");
                break;
            }
        } while (input);    
    return 0;
}

该代码有缺陷在于case里面会写很多个重复代码当使用函数指针数组则会减少该不足将主函数修改:

int main()
{
        int x, y;
        int input = 1;
        int ret = 0;
        int (*mid[5])(int*, int*) = {add,sub,mul,div};
        do
        {
            printf("*************************\n");
            printf(" 1:add 2:sub \n");
            printf(" 3:mul 4:div \n");
            printf("*************************\n");
            printf("请选择:");
            scanf("%d", &input);
            switch (input)
            {
            case 1:
            case 2:
            case 3:
            case 4:
                printf("输入操作数:");
                scanf("%d %d", &x, &y);
                ret = mid[input-1](x, y);
                ///ret = (*mid[input - 1])(x,y);这两种使用方法都可以。
                printf("ret = %d\n", ret);
                break;
            case 0:
                printf("退出程序\n");
                break;
            default:
                printf("选择错误\n");
                break;
            }
        } while (input);    
    return 0;
}

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

(1).书写形式:(以例说明)int (*(*p)[10])(int *,int *)=&arr;

拆分开来就是:最外层是函数指针==>内部的指针部分搞成数组指针===>再把数组指针进化成数组指针就行,一步一步来

二.回调函数。((o(^_ ^)o))

    • 书写形式:(以例说明)void(数据类型) part(函数名)(int (*pa)(int,int))里面是函数指针

    • 回调函数的意义(定义):

回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个

函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数

的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进

行响应

3.回调函数的使用☞模拟qsort函数

(1).介绍qsort函数:用于比较1个数组的元素之间的大小

//void qsort(void* base, //待排序的数组的起始地址
//      size_t num,    //元素个数
//     size_t width,  //一个元素的大小
//      int (*cmp)(const void* e1, const void* e2)//两个元素的比较函数
//         );
#include<stdio.h>
#include<string.h>
struct Str { char a[10]; int b; };
struct Str s[3] = { {"zhangsan",20}, {"lisi", 50}, {"wangwu", 33} };
int  part(const void*a ,const void*b)//比较函数形式固定
{return strcmp(((struct Str*)a)->a, ((struct Str*)b)->a);}
int main()
{   int a = sizeof(s) / sizeof(s[0]);
    qsort(s,a,sizeof(s[0]),part);//比较字符串
    return 0;
}

void* 是指空数据类型,因为不知到要操作的是哪种数据类型。

qsort默认是升序排列的

注意自己写的函数开始是void*要转化成要求的类型(important)

(2).实现模拟qsort函数(注意点和解释放在代码注释中)

#include <stdio.h>
#include <string.h>//定义结构体
typedef struct student
{char name[20];int score;}student;
//自定义比较函数  使用strcmp函数比较字符串大小
int  compare_student(const void* r1, const void* r2)
{
    return strcmp((*((student**)r1))->name, (*((student**)r2))->name);
}
//交换函数,使用char*指针一个字节一个字节交换
void swap(char* r1, char* r2, size_t width)
{
    size_t  i = 0;
    for (i = 0; i < width; i++)
    {
        char temp = 0;
        temp = *r1;
        *r1 = *r2;
        *r2 = temp;
        r1++;
        r2++;
    }
}
//自定义qsort函数的实现
void My_bubble_qsort(void* base, size_t num, size_t width, int (*compare)(const void* r1, const void* r2))
{
    size_t i = 0;
    size_t j = 0;
    for (i = 0; i < num - 1; i++)
    {
        for (j = 0; j < num - 1 - i; j++)
        {
            if (compare((char*)base + j * width, (char*)base + (j + 1) * width) > 0)
            {
                swap((char*)base + j * width, (char*)base + (j + 1) * width, width);
            }
        }
    }
}
int main()
{ student wangwu = { "wangwu",75 };
    student lisi = { "lisi",94 };
    student zhangsan = { "zhangsan",60 };
    student* arr_student[3] = { &wangwu,&lisi,&zhangsan };//定义结构体指针数组
    int i = 0;
    printf("排序前:\n");
    for (i = 0; i < 3; i++)
    {  printf("%s,%d\n", arr_student[i]->name, arr_student[i]->score); }
    My_bubble_qsort(arr_student, sizeof(arr_student) / sizeof(arr_student[0]), sizeof(arr_student[0]), compare_student);
    printf("\n排序后:\n");
    for (i = 0; i < 3; i++)
    {  printf("%s,%d\n", arr_student[i]->name, arr_student[i]->score); }
    return 0;
}

好了这就是今天的内容了,谢谢大家观看,希望大家多多指出不足。最后觉得小编写的还凑合的来个三连呀!

  • 31
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 26
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 26
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值