c语言函数不能嵌套定义,但可以嵌套调用。 c语言的函数代表在代码区一段连续内存的首地址,其也讲究字节对齐。
本质上是一个指针,该指针指向一个函数首地址
返回类型T (*函数名)(形参列表);
如:bool (*turnOnTv)(struct s * tv); bool (*tffTv)(struct s * tv);
tffTv=turnOffTv;(假设turnOffTv是定义的一个函数)
赋值直接把是函数名即可,不需要带参数
(*func)(实参列表);
(*tffTv)(tvBean);调用时有没有*都行
二、指针函数
指针函数它是一个函数,只不过这函数返回一个指针类型。如以下就是一个指针函数
char * getWeekDayOfName(int c);
函数名与*号不能用括号括起来,如果括起来就变成了函数指针了。
定义形式如下:
返回类型 (*函数数组名[大小]) (函数形参列表)
其中函数数组名的大小一定要指定,要不然会产生内存泄露,通过函数指针数组把形参类型相同的函数保存在一起,示例:
1、定义函数指针数组
bool (*arrayF[2])(struct s * tv);//函数指针数组
2、给函数指针数组赋值
arrayF[0]=turnOnTv;
arrayF[1]=turnOffTv;
arrayF[1](tvBean);
不定参数函数就是函数的参数是不定的,便至少要有一个参数,如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; } |
传统c函数定如下如下所示:
int max(a,b)int a;int b{……}
函数作参数,可以作当参数的函数有条件的执行,如调用函数获得了某个信号量之后才执行作参数的函数名。函数名作参数是win32控件的事件驱动编程的根本。
函数名作参数,只需要传递函数名,不再需要传递函数名相关的形参,需要声明时要声明完整。函数作参数就是传递一个函数地址给一个函数
c99引起了关键字inline,这个就是用来定义内函数的。 内联函数减少的调用的开销
c的函数不能返回数组与函数,但是可以返回数组指针与函数指针,定义一个返回函数指针的指针函数,这个会把一般人弄疯的。
例:
1、声明
typedef double (*funCtion)(struct s * tv);
funCtion (*f1)(double(*getL)(struct s * tv));//声明一个返回函数指针的函数指针变量
2、定义
funCtion getFunction(double(*func)(TvStruct * tv))
{
return func;
}
#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; } } |
评论