指针函数和函数指针的理解与应用

指针函数

指针函数, 即返回值为指针的函数, 本质上是一个函数, 我们先看下面实例:

#include <stdio.h>    
#include <time.h>    
int year;    
int mon;    
int day;    
char* GetDate();    
int main() {    
  char* current = GetDate();    
  printf("今天是:%s\n", current);    
  return 0;                                                                                                                             
}    
char* GetDate() {    
  // 静态变量在函数调用结束后不会被释放    
  static char string[30] = {0};    
  time_t timep;    
  struct tm* p_time;    
  time(&timep);    
  p_time = gmtime(&timep);    
  year = p_time->tm_year + 1900;    
  mon = p_time->tm_mon + 1;    
  day = p_time->tm_mday;    
  sprintf(string, "%d-%d-%d", year, mon, day);    
  return string;    
}    

效果图:
在这里插入图片描述
以上是获取当前时间的一个指针函数–>GetDate, 是一个返回char类型指针的函数

函数指针

函数指针, 即指向函数的指针, 本质上是一个指针, 注意下面例子:

#include <stdio.h>    
void Eat(int num);    
void Play(int num);    
void Sleep(int num);    
int main() {    
  void(*dosomeing)(int);    
  dosomeing = Eat;    
  dosomeing(2);    
  dosomeing = Play;    
  dosomeing(5);    
  dosomeing = Sleep;    
  dosomeing(7);                                                                                                                         
  return 0;    
}    
void Eat(int num) {    
  printf("我吃了 %d 碗饭\n", num);    
}    
void Play(int num) {    
  printf("我玩了 %d 局游戏\n", num);    
}    
void Sleep(int num) {    
  printf("我睡了 %d 个小时\n", num);    
}    

以上可以看出, 函数指针可以引用指定类型的函数, 使得在调用相同类型的函数时可以更加灵活.

其实函数指针和数组结合(指针数组)可以实现典型的表驱动, 表驱动通过将相同类型的函数以指针的形式储存在数组中, 在调用过程中直接可以通过索引调用即可, 减少了if else条件的嵌套, 大大降低了程序的圈复杂度, 提高了效率:

#include <stdio.h>                                                                                                                      
int Add(int a, int b);
int Minus(int a, int b);
int Multiply(int a, int b);
int Divide(int a, int b);
int main() {
  int choice = 0;
  int result = 0;
  //函数指针类型
  typedef int(*T)(int, int);
  T menu[] = {
    Add,
    Minus,
    Multiply,
    Divide
  };
  printf("1.加法\n");
  printf("2.减法\n");
  printf("3.乘法\n");
  printf("4.除法\n");
  printf("请选择:");
  scanf("%d", &choice);
  if (choice > 0 && choice < 5) {
  	//等同result = (*menu)[choice - 1](4, 2);
    result = menu[choice - 1](4, 2);
  }
  printf("%d\n", result);
  return 0;
}
int Add(int a, int b) {                             
  return a + b;                                     
}                                                   
int Minus(int a, int b) {                           
  return b - a;                                     
}                                                   
int Multiply(int a, int b) {                        
  return a * b;                                     
}                                                   
int Divide(int a, int b) {                          
  if (b != 0) {                                     
    return a / b;                                   
  }
 return 0;
}  

这就是表驱动(转移表)的典型应用, 其中不仅涉及到了函数指针的应用, 同时又涉及到了指针数组的知识, 对于指针数组的概念和应用理解不深入的, 可以参考下方链接, 希望能帮助你:

指针数组和数组指针

有一个值得注意的点, 我们就Add函数而言, 以下两两等价:


	T = Add;
	T = &Add;

	result = menu[0](4, 2);
	result = (*menu)[0](4, 2);
	

这说明, 函数名本身就是一个指针, 与数组不同的是, 对函数名取地址的效果和不取函数名地址的效果完全一样, 按理来说, 对对函数名解引用更符合我们对函数指针的理解, 但是其实参数列表()已经起到了解引用的作用了

希望本篇文章能给大家带来帮助, 欢迎大家的评论和建议

  • 18
    点赞
  • 83
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值