《C语言教程》19章 函数指针和函数数组

[复制链接]
1268|7
 楼主| niuyaliang 发表于 2015-3-17 20:42 | 显示全部楼层 |阅读模式
许多人听到这个名字就感到害怕,指针本身就没有完全搞懂,又有什么双重指针,现在这个东东非把我头搞昏不可。其实并没有那么可怕,但前面所讲的基础的确必须扎实。经小雅一分析,你会觉得指针并不难,真正难的是你没有找到好教程(玩笑)。
 楼主| niuyaliang 发表于 2015-3-17 20:42 | 显示全部楼层
一、指向标签的指针
指针的好处就是,你只要对指针变量赋一个地址,你就可以通过这个地址去代替那个变量,从而操作那个变量上的数据。指针变量如果没有赋值,就不能操作数据,因此你必须要将某个变量的地址赋给指针变量,也就是让这个指针有了空间。动态分配空间也是先申请一块空间,然后将这块空间的地址赋给这个指针变量。
 楼主| niuyaliang 发表于 2015-3-17 20:42 | 显示全部楼层
在C语言中不仅仅是变量的地址可以赋给指针,goto语句用的标签也可以赋给指针。标签其实就是一个地址,学过汇编语言的人就特别清楚这一点。下面这个例子是在Red Hatt Linux下用gcc编译实现的,遗憾的是Windows下并不支持。不过,如果我们能理解指针的功能也就达到目的了。
  1. #include <stdio.h>

  2. int main(void)
  3. {
  4.     void *ptr ;
  5.     int num;

  6.     scanf("%d", &num);
  7.     if (num < 10) {
  8.         ptr = &&succeed ;
  9.     } else {
  10.         ptr = &&failure ;
  11.     }
  12.     goto *ptr ;

  13. succeed:
  14.     printf("成功!") ;
  15.     return 0;

  16. failure:
  17.     printf("失败!") ;
  18.     return -1 ;
  19. }
 楼主| niuyaliang 发表于 2015-3-17 20:42 | 显示全部楼层
二、指向函数的指针
函数指针并不是指函数的地址象指针一样可以被赋值,而是指将函数的固定地址赋给指针变量,从而用指针来代替函数名来操作。
 楼主| niuyaliang 发表于 2015-3-17 20:43 | 显示全部楼层
一个函数定义好之后,它和变量一样,也有一个固定的地址,我们把这个地址赋给指针变量,这个指针就可以充当函数来使用。但要注意一点,函数的地址赋给指针变量的方法有点特殊,不能与普通变量一样赋值,否则编译系统就会误解成指针和函数结果的某种运算了。

  1. #include <stdio.h>

  2. //申明一个函数指针的类型。相当于函数申明。
  3. typedef int (*pType) (int) ;

  4. int fact(int number)
  5. {
  6.     int i , ret = 1 ;

  7.     for (i=1; i<=number; i++) {
  8.         ret *= i ;
  9.     }

  10.     return ret ;
  11. }

  12. int main(void)
  13. {
  14.     int num ;

  15.     pType pt;     //定义一个函数指针类型的变量

  16.     pt = fact;    //将函数fact的地址赋给pt

  17.     scanf("%d", &num);
  18.     printf("%d的阶层=%d \n", num, fact(num));    //这是普通的函数调用
  19.     printf("%d的阶层=%d \n", num, (*pt)(num));   //这是函数指针的调用方法。注意:*pt一定要用括号括起来。

  20.     return 0;
  21. }

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| niuyaliang 发表于 2015-3-17 20:43 | 显示全部楼层
上例中typedef语句在后面章节中细说,是用来自定义一个数据类型。当前的语句是typedef的特殊用法,pType是数据类型的名称,可以自己定,一般习惯用法全用大写。*pType两边的括号是必须的,是定义函数指针的标志。(*pType)前面的“int”数据类型是函数的返回值的数据类型,不是任意指定的,是你想要函数指针指向的函数的返回值的数据类型,当前例子中“fact”的返回值的数据类型。(*pType)后面和括号是参数,当前例子中“fact”后面的数据类型相一致。
上例中如果没有第04行的申明,第21行也可改为直接定义。“int (*pt) (int) ;”
 楼主| niuyaliang 发表于 2015-3-17 20:44 | 显示全部楼层
三、函数指针的应用
函数指针经常被使用,但初学者或一般的开发者却很少使用。限于自身水平不高,小雅也只能很肤浅地、象征性地举例说明。

  1. #include <stdio.h>

  2. //申明一个函数指针的类型
  3. typedef void (*pType) (int, int) ;

  4. void max(int m, int n)
  5. {
  6.     printf("最大值=[%d]\n", m>n ? m : n) ;
  7.     return ;
  8. }

  9. void min(int m, int n)
  10. {
  11.     printf("最小值=[%d]\n", m<n ? m : n) ;
  12.     return ;
  13. }

  14. void fsq(int m, int n)
  15. {
  16.     printf("平方和=[%d]\n", m * m + n * n) ;
  17.     return ;
  18. }

  19. //定义一个用函数指针做参数的函数
  20. void process(int num1, int num2, pType pt) {
  21.     (*pt)(num1, num2);
  22. }

  23. int main(void)
  24. {
  25.     int x, y, i ;
  26.     pType arr[] = {max, min, fsq};    //定义一个函数指针类型的数组

  27.     printf("请输入x和y的值:");
  28.     scanf("%d,%d", &x, &y) ;

  29.     //用法一
  30.     process(x, y, max);    //将函数max的地址作实参数
  31.     process(x, y, min);    //将函数min的地址作实参数
  32.     process(x, y, fsq);    //将函数fsq的地址作实参数

  33.     printf("\n");

  34.     //用法二
  35.     for (i=0; i<3; i++) {
  36.         arr[i](x, y);      //循环调用三个函数
  37.     }

  38.     return 0;
  39. }

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
xad74 发表于 2015-3-18 20:46 | 显示全部楼层
好,高受教了:D
您需要登录后才可以回帖 登录 | 注册

本版积分规则

212

主题

2427

帖子

7

粉丝
快速回复 在线客服 返回列表 返回顶部