指针进阶

一.函数指针数组

          1概念:  数组是一个存放相同类型数据的存储空间,把函数地址存放在一个数组中,那么这个数组叫做函数指针数组。其语法为 int(*parr1[10]();

通过前面的课程的学习,我们已经掌握了函数指针的用途,要想在此基础上理解函数指针数组,必须从函数指针来进行拓展,下面有一例函数指针的用途,试试看你有没有更好的方法对下面例子进行改进。

          

#include<stdio.h>
void menu()
{
    printf("**************************************\n");
    printf("*****1.add   2.sub********************\n");
    printf("*****3.mul    4.div*******************\n");
    printf("*****0.exit***************************\n");
} 
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;
}    

int main()
{      
      int input = 0;
      int ret = 0;
      d0
      {
         menu();
         printf("请选择:>\n");
         scanf("%d",&input);
         printf("请输入2个操作数:>");
         scanf("%d %d",&x,&y);
         switch(input)
         {
           case 1:
                ret=Add(x,y);
                printf("%d\n",ret);
                 break;
           case 2:
                  ret=sub(int x,int y);
                 printf("%d\n",ret);
                 break;
           case 3:
                    ret= mul(int x,int y);
                    printf("%d\n",ret);
                  break;
           case 4:
                    ret= div(int x,int y);
                    printf("%d\n",ret);
                  break;
             case 0:
                  printf("退出计算器\n");
                  break;
           default:
                   printf("选择错误\n);
                   break;
          }
      }while(input);
      return 0 ;
}

  很明显上述代码看起来不太简洁,试着优化一下代码使其看起来简单明了。在选择加减乘除代码中可以放在一个函数中进行运行。

 

#include<stdio.h>
void menu()
{
    printf("**************************************\n");
    printf("*****1.add   2.sub********************\n");
    printf("*****3.mul    4.div*******************\n");
    printf("*****0.exit***************************\n");
} 
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 clc(int(*pf)(int,int)
{
     int x = 0;
     int y = 0;
     int ret = 0;
     scanf("%d %d",&x,&y);
     ret = pf(x,y);
     printf("%d\n,ret);
}
   

int main()
{      
      int input = 0;
    
      d0
      {
         menu();
        
         switch(input)
         {
           case 1:
               clc(Add);
                 break;
           case 2:
                 clc(sub);
                 break;
           case 3:
                   clc(mul);
                  break;
           case 4:
                    clc(div);
                  break;
             case 0:
                  printf("退出计算器\n");
                  break;
           default:
                   printf("选择错误\n);
                   break;
          }
      }while(input);
      return 0 ;
}

上述代码通过把函数的地址传过去用函数指针int(*pf)(int ,int)接收,通过pf再次找到需要运行的函数使其相加减。

上述函数的返回类型,参数都一样,所以可以利用函数指针数组来进行在一次的优化。

#include<stdio.h>
void menu()
{
    printf("**************************************\n");
    printf("*****1.add   2.sub********************\n");
    printf("*****3.mul    4.div*******************\n");
    printf("*****0.exit***************************\n");
} 
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;
} 

   
int main()
{
    int (*pf)(int,int)=Add;
     int (*arr[4](int,int)={Add,sub,mul,div};
     int i= 0;
    for(i=0;i<4;i++)
   {
      int ret = arr[i](4,8);
    printf("%d",ret);
   }
    return 0;
}

二,回调函数

回调函数就是一个通过函数指针调用的函数,如果你把函数指针作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数,回调函数不是由该函数的实现方式直接调用,而是在特定的事件或条件发生时由另一方调用的,用于该事件或者条件的响应。

我们先回想学数组时写的冒泡排序,冒泡排序可以快速进行排序,但只能对整数进行快排,如果对于浮点数等非整数快排那么冒泡排序则不能用,能不能在冒泡排序的基础上进行改进使其快速进行非整数的快排。

冒泡排序的代码:

#include<stdio.h>
bubble_sort(int arr[],int sz)
{
    int i = 0;
    for(i=0;i<sz-1;i++)
    {
     int j = 0;
     for(j=0;j<sz-1-i;j++)
    {
          if(arr[j]>arr[j+1]
          {
            int tmp = arr[j];
            arr[j] = arr[j+1];
            arr[j+1] = tmp;
           }
    }
}
int main()
{
     int arr[]={9,8,7,6,5,4,3,2,1,0};
     int sz = sizeof(arr)/sizeof(arr[0]);
     bubble_sort(arr,sz);
     for(i=0;i<sz;i++)
      {
         printf("%d,arr[i};
      }
     return 0;
     
}

想达到冒泡排序的功能,库函数qsort可以不单单为整数排序,它的功能十分强大。要想了解该函数可以打开MSDN查找该函数的功能。其结果如下:

 void*base:起始位置

size_tnum:元素个数

width:元素大小(字节)

const void*el:第一个元素

const void*e2:第二个元素

int cmp_int(const void*e1,const void*e2)
{
        return (*(int*)e1-*(int*)e2);
}
int main()
{
     int arr[]={9,8,7,6,5,4,3,2,1,0};
     int sz = sizeof(arr)/sizeof(arr[0]);
     qsort(arr,sz,sizeof(arr[0]),cmp_int);
     for(i=0;i<sz;i++)
      {
         printf("%d,arr[i};
      }
     return 0;
     
}

说明:return (*(int*)e1-*(int*)e2); 其中把void*e1和e2强制类型转换为int*,因为void*是无具体类型的指针,可以接收任意类型的地址,所以不能用解引用操作,也不能+-整数。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值