打印

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

[复制链接]
907|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
沙发
niuyaliang|  楼主 | 2015-3-17 20:42 | 只看该作者
一、指向标签的指针
指针的好处就是,你只要对指针变量赋一个地址,你就可以通过这个地址去代替那个变量,从而操作那个变量上的数据。指针变量如果没有赋值,就不能操作数据,因此你必须要将某个变量的地址赋给指针变量,也就是让这个指针有了空间。动态分配空间也是先申请一块空间,然后将这块空间的地址赋给这个指针变量。

使用特权

评论回复
板凳
niuyaliang|  楼主 | 2015-3-17 20:42 | 只看该作者
在C语言中不仅仅是变量的地址可以赋给指针,goto语句用的标签也可以赋给指针。标签其实就是一个地址,学过汇编语言的人就特别清楚这一点。下面这个例子是在Red Hatt Linux下用gcc编译实现的,遗憾的是Windows下并不支持。不过,如果我们能理解指针的功能也就达到目的了。
#include <stdio.h>

int main(void)
{
    void *ptr ;
    int num;

    scanf("%d", &num);
    if (num < 10) {
        ptr = &&succeed ;
    } else {
        ptr = &&failure ;
    }
    goto *ptr ;

succeed:
    printf("成功!") ;
    return 0;

failure:
    printf("失败!") ;
    return -1 ;
}

使用特权

评论回复
地板
niuyaliang|  楼主 | 2015-3-17 20:42 | 只看该作者
二、指向函数的指针
函数指针并不是指函数的地址象指针一样可以被赋值,而是指将函数的固定地址赋给指针变量,从而用指针来代替函数名来操作。

使用特权

评论回复
5
niuyaliang|  楼主 | 2015-3-17 20:43 | 只看该作者
一个函数定义好之后,它和变量一样,也有一个固定的地址,我们把这个地址赋给指针变量,这个指针就可以充当函数来使用。但要注意一点,函数的地址赋给指针变量的方法有点特殊,不能与普通变量一样赋值,否则编译系统就会误解成指针和函数结果的某种运算了。

#include <stdio.h>

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

int fact(int number)
{
    int i , ret = 1 ;

    for (i=1; i<=number; i++) {
        ret *= i ;
    }

    return ret ;
}

int main(void)
{
    int num ;

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

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

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

    return 0;
}

使用特权

评论回复
6
niuyaliang|  楼主 | 2015-3-17 20:43 | 只看该作者
上例中typedef语句在后面章节中细说,是用来自定义一个数据类型。当前的语句是typedef的特殊用法,pType是数据类型的名称,可以自己定,一般习惯用法全用大写。*pType两边的括号是必须的,是定义函数指针的标志。(*pType)前面的“int”数据类型是函数的返回值的数据类型,不是任意指定的,是你想要函数指针指向的函数的返回值的数据类型,当前例子中“fact”的返回值的数据类型。(*pType)后面和括号是参数,当前例子中“fact”后面的数据类型相一致。
上例中如果没有第04行的申明,第21行也可改为直接定义。“int (*pt) (int) ;”

使用特权

评论回复
7
niuyaliang|  楼主 | 2015-3-17 20:44 | 只看该作者
三、函数指针的应用
函数指针经常被使用,但初学者或一般的开发者却很少使用。限于自身水平不高,小雅也只能很肤浅地、象征性地举例说明。

#include <stdio.h>

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

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

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

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

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

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

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

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

    printf("\n");

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

    return 0;
}

使用特权

评论回复
8
xad74| | 2015-3-18 20:46 | 只看该作者
好,高受教了:D

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

212

主题

2427

帖子

7

粉丝