指针解析(三)(原)


    不知不觉,指针解析来到了第三篇。本篇想讲的内容是有点高级,也有晦涩。说到高级和晦涩,有些人就不同意了。不就些基础内容嘛,何必用高级一次呢?我想我是假借高级一词,重点在“有点”。我倒不能说有点猥琐,有点恶心吧。吐舌鬼脸

    我们都知道,程序中的每个函数都位于内存的某个位置上,所以就存在指向那个位置上的指针。知道了这个道理之后呢,我们来看看以下这些声明是怎么一回事?

int f;        // 整型变量,这个鬼都知道
int *f;    // 一个指向整型的指针,这个鬼也知道
 
int f();    // 返回类型为整型的函数
int *f();    // 返回类型为一个指向整型指针的函数
 
// 以上都很平常,都是正常情况
 
int (*f)();    // 这是神马?.....这是函数指针,一个返回类型为整型的,不接受输入参数的函数指针
int *(*f)();    // 这个也是函数指针,一个返回类型为指向整型指针的,不接受输入参数的函数指针
 
int (*f[])();  // 这个有点晕!这是一个数组,其元素是函数指针
int *(*f[])(); // 这也是一个数组,其元素也是函数指针,只是返回类型和上面不一样

    指针真是强大,伤不起破碎的心

    看过上面的声明之后,我们可以进入函数指针的世界了。现在展示一个函数指针最基本的调用:

#include <stdio.h>
 
void MyFun(int );    // 要调用的函数声明
 
void (*FunP)(int );    // 声明的函数指针,接受一个int类型的参数,返回值为空的函数指针
 
int main(int argc, char* argv[])
{
    MyFun(1);        // 这里将直接调用MyFun函数
 
    FunP = &MyFun;    // 将MyFun函数的地址赋给FunP,其实,FunP = MyFun,也可以,好玩吧。
 
    (*FunP)(2);        // 这里通过函数指针FunP”变量“来调用MyFun函数,注意变量两字啊。
    FunP(3);        // 你可以这样调用
}
 
void MyFun(int x) 
{
    printf("%d\n",x);
}

    最近我发觉,有些东西还是直接贴代码好。不然真不知道怎么表达尴尬?囧啊!以上的调用过程显示了函数指针的奥妙啊。基于上面的思路,我们在进行拓展太阳。我们都知道typedef这个参数,其作用是声明自定义数据类型,配合各种原有数据类型来达到简化编程的目的的类型定义关键字。例如:

typedef char data_type;

    这个可帮了大忙了。我修改数据类型之类的,都可以灰常快速的进行。那时牵一发而动全身啊恶魔!当然,我现在不说它神马牵一发而动全身的问题。我想让大家看懂下面这个问题:

 typedef int (*Pfun) (const char *, const char *);    // 这个看起来有点晕吧!

    施主莫晕!吐舌鬼脸这样只是定义一个函数指针类型,莫怕莫怕!这个声明引入了 Pfun 类型作为函数指针的同义字,该函数有两个 const char * 类型的参数以及一个 int 类型的返回值。当你适应了这个之后,我想介绍回调函数了。神马是回调函数?用户把一个函数指针做为一个参数传递给其他函数,后者将“回调”用户的函数。尼玛,这个解释够拗口的!直白点就是说与指针函数一致的函数可以通过这个回调动作,让其他函数使用!这个还是有点拗口!书呆子看了下面这个例子就会好多:

#include <stdio.h>
 
int CompareImpl(void const *a, void const *b );            // 要调用的函数声明
 
typedef int (*Compare) (void const *, void const *);    // 声明的函数指针,接受一个void类型的指针参数,返回值为整型的函数指针
 
int Equal(int , int , Compare);                            // 回调函数的入口是Compare,至于怎么Compare那就要看传入的函数是如何了。
 
int main(int argc, char* argv[])
{
    printf("结果为:%d\n", Equal(1, 2, CompareImpl));        // 这里我们传入了CompareImpl,说明在*这个地方时调用CompareImpl函数来进行比较
    return 0;
}
 
int CompareImpl(void const *a, void const *b )
{
    if (*(int *)a == *(int *)b)        // 这里很好玩,我们将void指针转换成int类型。这个函数就被我们改照成了接受
    {
        return 1;
    } 
    else
    {
        return 0;
    }
}
 
int Equal(int a, int b, Compare compare)
{
    return compare(&a, &b);                                // *
}

    以上的例子应该是最浅显的回调解释了太阳。如果还是不明白,去翻翻书和放狗出去查查相关的资料了吐舌笑脸。以上的compare让大家想起神马呢?我想说,这让我想起了模板!用void指针和函数指针来模拟模板的一些初级功能!

    接下来要说的是转移表,这个号称是switch/case杀手!到底怎么杀呢?看看一下的代码对比就知道了:

switch ()
{
case A:
    func1(1, 2);
    break;
case B:
    func2(1, 2);
    break;
case C:
    func3(1, 2);
    break;
case D:
    func4(1, 2);
    break;
 
default:
    break;
}
// 纳尼,这么长!!
// 现在你可以用这样来代替
 
void func1(double, double);
void func2(double, double);
void func3(double, double);
void func4(double, double);
 
void (*pfunc[])(double, double) = 
{func1, func2, func3, func4    };
 
// 调用的时候
pfunc[1](1,2);    // 调用的是func2(1, 2)

    明眼人就看出来了,这是函数指针数组的应用了太阳

    结了,就说到这里吧星星!睡觉了。。。。。沉睡的弯月

 

参考文献

1. 《C语言程序设计》

2. 《C和指针》

3. 《C专家编程》

4. 百度百科的typdef的解释。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM