c/c++支持可变参数的函数
glist; int buffing; int retval; va_start(arglist, format); //arglist指向format后面的第一个参数 ...//不关心其它代码 retval = _output(stdout,format,arglist); //把format格式和参数传递给output函数 ...//不关心其它代码 return(retval); } 我们先模仿这个函数写一个:
运行一下看看,哈,错误百出。仔细分析原因,根据宏的定义我们知道 arglist是一个指针,它指向第一个可变的参数,但是所有的参数都位于栈中,所以arglist指向栈中某个位置,通过arglist的值,我们可以直接查看栈里面的内容: arglist -> 指向栈里面,内容包括 0067FD78 E0 FD 67 00 //指向字符串"This is a test" 0067FD7C 0A 00 00 00 //整数 i 的值 0067FD80 14 00 00 00 //整数 j 的值 0067FD84 71 3D 0A D7 //double 变量 f, 占用8个字节 0067FD88 A3 B0 28 40 0067FD8C 00 00 00 00 如果直接调用 printf(fmt, arglist); 仅仅是把arglist指针的值0067FD78入栈,然后把格式字符串入栈,相当于调用: printf(fmt, 0067FD78); 自然这样的调用肯定会出现错误。 我们能不能逐个把参数提取出来,再传递给其它函数呢?先考虑一次性把所有参数传递进去的问题。 如果调用的是系统库函数,这种情况下是不可能的。因为提取参数是在运行态,而参数入栈是在编译的时候确定的。无法让编译器预知运行态的事情给出正确的参数入栈代码。而我们在运行态虽然可以提取每个参数,但是无法将参数一次性全部压栈,即使使用汇编代码实现起来也是很困难的,因为不单是一个简单的push代码就可以做到。 如果接受参数的函数也是我们自己写的,自然我们可以把arglist指针入栈,然后在函数中自己解析arglist指针里面的参数,逐个提取出来处理。但是这样做似乎没有什么意义,一方面,这个函数没有必要也做成可变参数函数,另一方面直接在第一个函数中解析参数,然后处理不是更简单么? 我们唯一可以做到的是,逐个解析参数,然后循环中调用其它可变参数函数,每次传递一个参数。这里又有一个问题,就是参数表中的不可变参数的传递问题,有些情况下不能简单的传递,以上面的例子为例, 通常我们解析参数的同时,还需要解析格式字符串:
|
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |