加入收藏 | 设为首页 | 会员中心 | 我要投稿 我爱制作网_池州站长网 (https://www.0566zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

指针函数、函数指针数组、指向函数指针数组的指针

发布时间:2022-12-02 10:50:50 所属栏目:PHP教程 来源:
导读:  指针函数、函数指针数组、指向函数指针数组的指针 1.函数 1.1 指针函数

  本质是一个函数,返回值是一个指针类型。

  注意:

  指针函数不能返回局部变量的地址。(函数结束,对应开辟的空间使
  指针函数、函数指针数组、指向函数指针数组的指针 1.函数 1.1 指针函数
 
  本质是一个函数,返回值是一个指针类型。
 
  注意:
 
  指针函数不能返回局部变量的地址。(函数结束,对应开辟的空间使用权回收,即使返回了地址,也无权访问)
 
  可以返回:
 
  1.全局变量的地址
 
  2.static修饰的局部变量的地址
 
  3.由函数传递过来的地址(如:strcpy, strcat)
 
  #include
  int *my_add1(int x, int y){
   int temp = x+y;
   return &temp;//错误的 局部变量占用的内存空间在函数结束时 就被回收了
  }
  int value = 0;
  int *my_add2(int x, int y){
   value = x+y;
   return &value;//可以返回全局变量的地址
  }
  int *my_add3(int x, int y){
   static int temp = 0;//static修饰的局部变量的地址
   temp = x+y;
   return &temp;
  }
  int main(int argc, const char *argv[])
  {
   int a = 10;
   int b = 20;
   //int *p = my_add1(a, b);
   //printf("*p = %d\n", *p);
  
   int *p = my_add2(a, b);
   printf("*p = %d\n", *p);
   int *p2 = my_add3(a, b);
   printf("*p2 = %d\n", *p2);
  
   return 0;
  }
  1.2 函数指针
 
  本质是一个指针,指向一个函数。
 
  格式:
 
  ? 返回值类型 (*函数指针名)(函数的形参表);
 
  返回值类型  (*函数指针名)(函数的形参表);
   int (*p)(int, int) = NULL;
   p = my_add;  
   int ret2 = p(a, b);
  例:
 
  #include
  int my_add(int x, int y){
   return x+y;
  }
  int main(int argc, const char *argv[])
  {
   int a = 10;
   int b = 20;
   int ret1 = my_add(a, b);
   printf("ret1 = %d\n", ret1); //30
   //定义一个函数指针 指向 my_add 函数
   int (*p)(int, int) = NULL;
   p = my_add;  //函数名 就是函数的首地址
   //函数指针指向函数之后 就可以通过函数指针调用函数了
   int ret2 = p(a, b);
   printf("ret2 = %d\n", p(a, b)); //30
   return 0;
  }
  函数指针的典型使用场景----回调函数 (重点)
 
  #include
  int my_add(int x, int y){
   return x+y;
  }
  int my_sub(int x, int y){
   return x-y;
  }
  //所谓的回调函数是指用函数指针做位函数的形参
  //在函数中通过函数指针来调用函数 具体调用的是哪一个
  //取决 jisuan这个函数的调用者给它传的第三个参数是什么
  //传什么 通过函数指针调用的就是什么 ----所以叫做回调函数
  int jisuan(int x, int y, int (*p)(int, int)){
   return p(x, y);
  }
  int main(int argc, const char *argv[])
  {
   int a = 10;
   int b = 20;
   printf("%d\n", jisuan(a, b, my_add)); //30
   printf("%d\n", jisuan(a, b, my_sub)); //-10
   return 0;
  }
  linux系统中,signal函数中就是使用了回调函数来实现的。
 
  #include
  typedef void (*sighandler_t)(int);
  sighandler_t signal(int signum, sighandler_t handler);
  //此处的 handler 是一个能指向 返回值为 void 形参列表为 (int)
  //的函数的 函数指针
  signal函数使用实例:
 
  ?
 
  #include
  #include
  #include
  void my_function(int signum){
   printf("hqyj\n");
  }
  int main(int argc, const char *argv[])
  {
   signal(SIGINT, my_function);
   while(1){
   printf("hello world\n");
   sleep(1);
   }
   return 0;
  }
  1.3 函数指针数组
 
  本质是一个数组,数组中的每个元素都是一个函数指针。
 
  格式:
 
  返回值类型  (*函数指针数组名[下标])(函数的形参表);
      int (*p[2])(int, int) = {NULL};
   p[0] = my_add;
   p[1] = my_sub;
  例:
 
  #include
  int my_add(int x, int y){
   return x+y;
  }
  int my_sub(int x, int y){
   return x-y;
  }
  int main(int argc, const char *argv[])
  {
   //定义了一个函数指针数组,数组中有2个元素
   //每个元素都是一个能指向 返回值为 int 形参列表为(int, int) 的函数的函数指针
   int (*p[2])(int, int) = {NULL};
   //取出数组的一个元素后 操作就和操作 一个函数指针是一样的了
   p[0] = my_add;
   p[1] = my_sub;
   //可以通过函数指针数组来调用函数
   int a = 10;
   int b = 20;
   printf("a+b = %d\n", p[0](a, b)); //30
   printf("a-b = %d\n", p[1](a, b)); //-10
   return 0;
  }
  1.4 指向函数指针数组的指针
 
  本质是一个指针,指向一个函数指针数组。
 
  格式:
 
  返回值类型 (*(*指针名))(函数的形参表);
      int (*(*p))(int, int) = NULL;
   p = arr;
  例如:
 
  #include
  int my_add(int x, int y){
   return x+y;
  }
  int my_sub(int x, int y){
   return x-y;
  }
  int main(int argc, const char *argv[])
  {
   int (*arr[2])(int, int) = {my_add, my_sub};
   //定义一个指针 指向函数指针数组
   int (*(*p))(int, int) = NULL;
   p = arr;
   //可以指向函数指针数组的指针来调用函数
   int a = 10;
   int b = 20;
   printf("a+b = %d\n", p[0](a, b)); //30
   printf("a-b = %d\n", (*(p+1))(a, b)); //-10
   return 0;
  }
  类型(int举例)格式本质
 
  指针函数
 
  int *my_add1(int x, int y)
 
  本质是一个函数,返回值是一个指针类型。
 
  函数指针
 
  int (*p)(int, int) = NULL;p = my_add;
 
  本质是一个指针,指向一个函数。
 
  函数指针数组
 
  int (*p[2])(int, int) = {NULL}; p[0] = my_add; p[1] = my_sub;
 
  本质是一个数组,数组中的每个元素都是一个函数指针。
 
  指向函数指针数组的指针
 
  int (**(*p))(int, int) = NULL; p = arr;
 
  本质是一个指针php指针,指向一个函数指针数组。
 
  2、typedef
 
  typedef 是用来给类型起别名的。
 
  例:
 
  #include
  typedef unsigned long long int ulli;
  //本来是定义变量的语句 如果前面加上了 typedef
  //原来的变量名 就变成了新的类型名
  int main(int argc, const char *argv[])
  {
   unsigned long long int m;
   m = 100;
   ulli n = 100;
   printf("m = %lld\n", m);//100
   printf("n = %lld\n", n);//100
   return 0;
  }
  C语言中常见的定义变量的语句:
 
  int a;
  int *a;
  int **a;
  int a[5];
  int a[3][4];
  int *a[5];
  int (*a)[5];
  int (*a)(int);
  int (*a[5])(int);
  int (*(*a))(int);
  把变量名去掉,剩下的就都是类型名了
 
  int ;
  int *;
  int **;
  int [5];
  int [3][4];
  int *[5];
  int (*)[5];
  int (*)(int);
  int (*[5])(int);
  int (*(*))(int);
  本来是定义变量的语句 如果前面加上了 typedef
 
  原来的变量名 就变成了新的类型名
 
  typedef int a;
  typedef int *a;
  typedef int **a;
  typedef int a[5];
  typedef int a[3][4];
  typedef int *a[5];
  typedef int (*a)[5];
  typedef int (*a)(int);
  typedef int (*a[5])(int);
  typedef int (*(*a))(int);
  typedef 和 define 有什么区别?
 
  1.宏定义是在预处理阶段完成替换的,而typedef是类型的重定义,在编译阶段检查;
 
  2.typedef要求结尾必须加分号 而宏定义不强制要求;
 
  3.typedef是给类型起别名,而宏定义只是一个简单的替换;
 
  #include
  #define hqyj1 int *
  typedef int * hqyj2;
  int main(int argc, const char *argv[])
  {
   int a = 10;
   int b = 20;
   //此时 p1 和 p2 都是指针
   hqyj2 p1, p2;
   p1 = &a;
   p2 = &b;
   //此时 q1 是指针  而 q2 就是一个普通的 int 变量
   hqyj1 q1, q2;
   q1 = &a;
   q2 = &b;
   return 0;
  }
 

(编辑:我爱制作网_池州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!