登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

仙剑奇侠传的博客

羽化成仙

 
 
 

日志

 
 

C语言之函数  

2011-08-10 16:55:53|  分类: C |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

 

c语言函数不能嵌套定义,但可以嵌套调用。 c语言的函数代表在代码区一段连续内存的首地址,其也讲究字节对齐。

  1. 函数指针

    本质上是一个指针,该指针指向一个函数首地址

    1. 定义函数指针,语法:

      返回类型T (*函数名)(形参列表);

      如:bool (*turnOnTv)(struct s * tv); bool (*tffTv)(struct s * tv);

    2. 函数指针赋值。因为该值是保留函数的值,函数名就是一个函数的首地址,赋值如下:

      tffTv=turnOffTv;(假设turnOffTv是定义的一个函数)

      赋值直接把是函数名即可,不需要带参数

    3. 函数指针调用,调用形式为

      (*func)(实参列表);

      (*tffTv)(tvBean);调用时有没有*都行

二、指针函数

指针函数它是一个函数,只不过这函数返回一个指针类型。如以下就是一个指针函数

char * getWeekDayOfName(int c);

函数名与*号不能用括号括起来,如果括起来就变成了函数指针了。

  1. 函数指针数组

    定义形式如下:

    返回类型 (*函数数组名[大小]) (函数形参列表)

     

    其中函数数组名的大小一定要指定,要不然会产生内存泄露,通过函数指针数组把形参类型相同的函数保存在一起,示例:

    1、定义函数指针数组

    bool (*arrayF[2])(struct s * tv);//函数指针数组

    2、给函数指针数组赋值

    arrayF[0]=turnOnTv;

    arrayF[1]=turnOffTv;

    1. 通过函数指针数组运行函数

      arrayF[1](tvBean);

  2. 不定参数函数

    不定参数函数就是函数的参数是不定的,便至少要有一个参数,如printf函数就是不定参数函数。

    语法如下:

    返回类型 函数名(参数1,…)

     

    int max(int num,...){

        int m=-0x7fffffff;

        va_list ap;

        va_start(ap,num);

        for(int i=0;i<num;i++){

            int t=va_arg(ap,int);

            if(t>m){

                m=t;

            }

        }

        va_end(ap);

    return m;

    }

  3. 传统c定义的函数

    传统c函数定如下如下所示:

    int max(a,b)int a;int b{……}

  4. 函数名当作参数

    函数作参数,可以作当参数的函数有条件的执行,如调用函数获得了某个信号量之后才执行作参数的函数名。函数名作参数是win32控件的事件驱动编程的根本。

    函数名作参数,只需要传递函数名,不再需要传递函数名相关的形参,需要声明时要声明完整。函数作参数就是传递一个函数地址给一个函数

  5. 内联函数

    c99引起了关键字inline,这个就是用来定义内函数的。 内联函数减少的调用的开销

  6. 定义一个返回函数指针的指针函数

    c的函数不能返回数组与函数,但是可以返回数组指针与函数指针,定义一个返回函数指针的指针函数,这个会把一般人弄疯的。

    例:

    1、声明

    typedef double (*funCtion)(struct s * tv);

    funCtion (*f1)(double(*getL)(struct s * tv));//声明一个返回函数指针的函数指针变量

    2、定义

    funCtion getFunction(double(*func)(TvStruct * tv))

    {

    return func;

    }

     

  7. 附录:一个源代码,演示了函数的用法:

    #include<stdio.h>

    #include<stdlib.h>

    #include<stdbool.h>

    #include<malloc.h>

     

    /*******************************

    演示函数指针

    演示函数返回函数指针

    演示函数指针数组

    演示函数作参数

    这儿以电视机对象进行演示

    电视机对象属性有:品牌、长、宽、厚、重

    对它操作的方法有:开电视、关电视、换台

    ******************************/

    // typedef double(*func)(struct s * tv);

    typedef struct s

    {

         char * marked;//电视机品牌

         double length;//电视机长

         double width;//电视机宽

         double deep;//电视机厚

         double weigth;//电视机重

         int currChannle;//当前频道

         bool (*turnOnTv)(struct s * tv);//函数指针变量

         bool (*turnOffTv)(struct s * tv);//函数指针变量

         double (*getValue)(double(*getL)(struct s * tv),struct s *tvBean);

         double (*getPropert)(struct s * tv);

         int (*next)(int channle);//函数指针

         double (*arrayF[3])(struct s * tv);//函数指针数组

         void (*getTvSize)(struct s * tv);//函数指针

         void (*exeTvMethod)(struct s * tv);

         void (*destroy)(struct s * tv);

    }TvStruct;

     

    TvStruct * tvStruct();//指针函数

    extern bool turnOnTv(TvStruct * );

    extern bool turnOffTv(TvStruct * );

    extern void destroy(TvStruct *);

    double getTvValue(double(*func)(TvStruct * tv),TvStruct * tvBean);

    extern void getTvSize(TvStruct * tv);

     

    extern double getWidth(TvStruct * tv);

    extern double getLength(TvStruct * tv);

    extern double getDeep(TvStruct * tv);

    extern void exeTvMethod(TvStruct * tv);

     

    int main(int arv,char * argc[]){

          

         TvStruct * tvBean=tvStruct();//构造TvStruct对象

         tvBean->getTvSize(tvBean);//执行TvStruct对象的方法

         tvBean->exeTvMethod(tvBean);//执行TvStruct对象的方法

         tvBean->destroy(tvBean);//清理TvStruct对象

         system("pause");

          

         return 1;

    }

     

    void exeTvMethod(TvStruct * tv){

    (tv->turnOnTv)(tv);

    tv->turnOffTv(tv);

    }

     

    void getTvSize(TvStruct * tv){

    if (tv->getValue!=NULL)

    {

         tv->getValue(tv->arrayF[0],tv);

    tv->getValue(tv->arrayF[1],tv);

         tv->getValue(tv->arrayF[2],tv);

    }

    }

    bool turnOnTv(TvStruct * tv){

        tv->currChannle=1;

        printf("电视机已开……\n");

        return tv->currChannle>0;

    }

     

    bool turnOffTv(TvStruct * tv){

        tv->currChannle=0;

        printf("电视机已关……\n");

        return tv->currChannle==0;

    }

     

    TvStruct * tvStruct(){

         TvStruct * tvBean =malloc(sizeof(TvStruct));

         tvBean->marked=malloc(100);//分配10个字符

         tvBean->marked="changhong";

         tvBean->length=1.5f;

         tvBean->width=0.5f;

         tvBean->weigth=30;

         tvBean->deep=0.2;

         tvBean->turnOnTv=turnOnTv;

         tvBean->turnOffTv=turnOffTv;

         tvBean->arrayF[0]=getWidth;

    tvBean->arrayF[1]=getLength;

         tvBean->arrayF[2]=getDeep;

         tvBean->getValue=getTvValue;

         tvBean->getPropert=getWidth;

         tvBean->getTvSize=getTvSize;

         tvBean->exeTvMethod=exeTvMethod;

         tvBean->destroy=destroy;

    printf("开始建立对象:%lx\n",(unsigned long)tvBean);

         return tvBean;

    }

     

    double getTvValue(double(*func)(TvStruct * tv),TvStruct * tvBean){

    double d=(*func)(tvBean);

    return d;

     

    }

    //得到宽

    double getWidth(TvStruct * tv){

        printf("电视机宽为%lf\n",tv->width);

        return tv->width;

    }

    //得到长度

    double getLength(TvStruct * tv){

        printf("电视机长为%lf\n",tv->length);

        return tv->length;

    }

     

    //得到厚度

    double getDeep(TvStruct * tv){

        printf("电视机厚为%lf\n",tv->deep);

        return tv->deep;

    }

     

     

    void destroy(TvStruct * tv){

    if (tv!=NULL)

         {

            if (tv->marked!=NULL)

             {

     

                 free(tv->marked);

                 tv->marked=NULL;

             }

             printf("开始析解对象:%lx\n",(unsigned long)tv);

             free(tv);

             tv=NULL;

         }

    }

  评论这张
 
阅读(183)| 评论(0)

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018