以下内容节选自“底层工作者手册之 嵌入式操作系统内核”中的4.3 节,这本手册讲述的是Wanlix和Mindows操作系统内核原理,更多资料请登陆www.ifreecoding.com下载。在学习C语言时,我们都使用过printf函数,这个函数可以根据个人需要,很灵活的向显示器终端打印数据,比如,我们可以按照下面的方式输出: printf("Wanlix & Mindows"); printf("%d, %c", i, j); 不知道你注意过没有,printf函数的参数个数是可变的,上面的第一个例子只有1个参数,第二个例子有3个参数,这点与我们一般所使用的函数是不同的。在Mindows中,我们仿造printf函数,将向内存打印的函数DEV_PutStrToMem也编写成一个参数可变的函数,下面我们一起来看看这是怎么实现的。 参数可变的函数原型定义为: void DEV_PutStrToMem(U8* pvStringPt, ...); 其中比较特别的是“...”,这三个点表示省略的参数。可变参数函数的原理非常简单,可变参数函数的参数不像我们前面讲过的那样,使用R0~R3寄存器传递参数,而是直接使用堆栈传递参数,而且这些参数都是连在一起存放的,而函数原型中第一个参数是固定的,我们可以获取到第一个参数的地址&pvStringPt,然后将这个地址加4就可以得到第二个参数的地址,再加4就是第三个参数的地址,依次类推,这样就可以获取到任意多的参数地址了,有了参数地址那么获取参数也就不成问题了。那么DEV_PutStrToMem函数怎么知道究竟有多少个参数呢?那些可变的参数是需要转换成第一个参数中%号后面的格式的,这样,我们只需要查找%号的个数确定可变参数的个数了。 file:///C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/ksohtml/wps_clip_image-30547.png 图 43 可变参数函数 可变参数函数的原型可以有多种形式,但必须要保证: 1.必须有第一个参数,通过这个参数才能获取到参数存放在栈中的首地址,后面的参数才是可变的。 2.在设计可变参数时需要能体现出可变参数的个数,如上面查找第一个参数中%号的方法,或者将第一个参数定义为可变参数的个数,或者其它方式。 在C语言标准头文件stdarg.h里面已经为可变函数定义了几个宏,使用这些宏也可以实现可变参数函数,原理都一样, 细节不再介绍了。 |