C51中的参数可变函数作为引导的例子:假设要编写一个函数,来求n个数中最大的一个
函数的声明像下面这样:unsignedcharmax(unsignedn,…);本文的目标就是实做这个函数
C语言栈空间的处理方式:我们很容易看懂这样的代码intsum(inta,intb){return(a+b);}voidmain(void){intx;x=sum(1,2);/*子函数的调用和返回*/While(1);}每一次子函数的调用和返回就伴随着一系列的压栈和出栈,但是“内存不可以泄露”,所以子函数返回后栈指针应该恢复到原来的位置,如下图所示:有两种修正栈的办法:一种是在子函数sum内进行处理,另一种在调用子函数sum结束的地方处理
这也就是C语言函数的栈空间处理的两种方式_cdecl和_stdcall,您可以把_cdecl和_stdcall想象成两个函数,一调用就修正栈指针,如下图_stdcall方式sum函数一旦编写好以后,修正栈的方法就固定了,以后函数的形参个数不能随意变化
如下图所示:这个函数在调用结束后要把盏指针回调3个单位,调节指针的工作固定在sum子函数的代码内
_cdecl方式sum函数内不做修正栈的工作,每次调用sum函数当返回时,编译器都重新帮助sum函数再修正一次栈空间,这样就允许了sum函数形参个数变化,反正这时sum函数又不操心入栈出栈的问题,它只关心运算处理,编译器知道这次调用入栈了多少,应该出栈多少,如下图示:_stdcall方式节约了ROM(计算机专业的人叫代码段),但是却让sum函数的形参个数不可以变化
_cdecl方式浪费了ROM,但是函数的形参个数可以变化
所以我们在VC++里会看到printf这样重要的函数,都是_cdecl方式的,但是动态链接库的函数一般都是_stdcall方式的
前者是实际需要,形参必须可以变化;后者因为大量被使用,必须考虑