C51参数可变函数

C51参数可变函数

ID:41028364

大小:82.00 KB

页数:5页

时间:2019-08-14

C51参数可变函数_第1页
C51参数可变函数_第2页
C51参数可变函数_第3页
C51参数可变函数_第4页
C51参数可变函数_第5页
资源描述:

《C51参数可变函数》由会员上传分享,免费在线阅读,更多相关内容在工程资料-天天文库

1、C51中的参数可变函数作为引导的例子:假设要编写一个函数,来求n个数中最大的一个。函数的声明像下面这样:unsignedcharmax(unsignedn,…);本文的目标就是实做这个函数。C语言栈空间的处理方式:我们很容易看懂这样的代码intsum(inta,intb){return(a+b);}voidmain(void){intx;x=sum(1,2);/*子函数的调用和返回*/While(1);}每一次子函数的调用和返回就伴随着一系列的压栈和出栈,但是“内存不可以泄露”,所以子函数返回后栈指针应该恢复到原来的位置,如下图所示:有两种修正栈的办法:一种是在子函数sum

2、内进行处理,另一种在调用子函数sum结束的地方处理。这也就是C语言函数的栈空间处理的两种方式_cdecl和_stdcall,您可以把_cdecl和_stdcall想象成两个函数,一调用就修正栈指针,如下图_stdcall方式sum函数一旦编写好以后,修正栈的方法就固定了,以后函数的形参个数不能随意变化。如下图所示:这个函数在调用结束后要把盏指针回调3个单位,调节指针的工作固定在sum子函数的代码内。_cdecl方式sum函数内不做修正栈的工作,每次调用sum函数当返回时,编译器都重新帮助sum函数再修正一次栈空间,这样就允许了sum函数形参个数变化,反正这时sum函数又不操

3、心入栈出栈的问题,它只关心运算处理,编译器知道这次调用入栈了多少,应该出栈多少,如下图示:_stdcall方式节约了ROM(计算机专业的人叫代码段),但是却让sum函数的形参个数不可以变化。_cdecl方式浪费了ROM,但是函数的形参个数可以变化。所以我们在VC++里会看到printf这样重要的函数,都是_cdecl方式的,但是动态链接库的函数一般都是_stdcall方式的。前者是实际需要,形参必须可以变化;后者因为大量被使用,必须考虑节约ROM(代码段)。但是在单片机里大家不必操心这些,KeilC51有自己的入栈出栈方式,参数可变函数能够成功运行。栈的指针:想象一下假设我

4、们编写好了一个参数可变函数,然后去调用它为我们工作。就像这样function(a,b,c,d,e),调用前形式参数被压入栈内,在function代码内部可以用栈指针去寻找这些参数,然后去使用。一提到栈的指针,大家马上就想到了sp,但是这样不好。要动用汇编指令,更麻烦的是汇编和C语言的结合,这是我们不想看到的场面。C语言里有其他办法解决这个问题,那就是利用标准库stdarg.h。这里面的一个数据类型和三个“函数”是我们最关心的:va_list//注意这是一个数据类型,就如同charva_start(形参1,形参2);va_arg(形参1,形参2);va_end(形参);它们的

5、用途马上就解释。实做unsignedcharmax(unsignedn,…)函数:这个函数就像他的名字所描述的一样,求n个数中最大的一个。假设我们编写好了这个函数,我们就可以去调用了:voidmain(void){unsignedcharM;M=max(5,20,45,55,80,95);while(1);//51单片机停机}M自然是返回95,调用这个函数前,5、20、45、55、80、95先被压栈,如下图所示:要操作这些数据,我们需要一个指向栈空间的指针pStack,我们可以利用下面方法定义这个指针:va_listpStack;下面我们想让pStack指向20,如下图:方

6、法是,调用函数va_start(pStack,n)。您也许很诧异倒低n是什么,那么我把全部的代码拷贝过来给您看看吧,它是这样的:va_start(pStack,n)很古怪,但是这个函数确实就是这么用的,这倒不是需要n的值,而是需要n这个符号。这样pStack马上就指向了n后续的参数。然后您一定想引用这个指针(*pStack)了吧?不行,都不知道pStack指向了什么类型的数据。我们需要利用函数va_arg(pStack,unsignedchar);这个函数依然很古怪,(1)这个函数使pStack感觉自己指向的是unsignedchar类型的数据(2)这个函数把栈指针pSta

7、ck所指向的内容返回来,并且按(1)的要求认为数据是unsignedchar(3)这个函数还调整指针pStack++,按(1)的要求跳过一个unsignedchar类型的数据单元这个函数自然也可以这样用va_arg(pStack,unsignedint),您能明白意思吧?一切的工作都做完了以后,我们要释放pStack指针,也就是利用函数va_end(pStack);这一步的意义我还没发现。算是按要求来吧。最后把全部代码给大家看看:#include#includeunsigned

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。