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指针里面的参数,逐个提取出来处理。但是这样做似乎没有什么意义,一方面,这个函数没有必要也做成可变参数函数,另一方面直接在第一个函数中解析参数,然后处理不是更简单么?
我们唯一可以做到的是,逐个解析参数,然后循环中调用其它可变参数函数,每次传递一个参数。这里又有一个问题,就是参数表中的不可变参数的传递问题,有些情况下不能简单的传递,以上面的例子为例, 通常我们解析参数的同时,还需要解析格式字符串:
#include
#include
#include
//测试一下这个,开个玩笑
void t(…)
{
printf(”\n”);
}
int mywrite(char *fmt, …)
{
va_list arglist;
va_start(arglist, fmt);
char temp[255];
strcpy(temp, fmt); //Copy the Format string
char Format[255];
char *p = strchr(temp,’%');
int i=0;
int iParam;
double fParam;
while(p != NULL)
{
while((*p< 'a' || *p>‘z’) && (*p!=0) ) p++;
if(*p == 0)break;
p++;
//格式字符串
int nChar = p - temp;
strncpy(Format,temp, nChar);
Format[nChar] = 0;
//参数
if(Format[nChar-1] != ‘f’)
{
iParam = va_arg( arglist, int);
printf(Format, iParam);
}
else
{
fParam = va_arg( arglist, double);
printf(Format, fParam);
}
i++;
if(*p == 0) break;
strcpy(temp, p);
p = strchr(temp, ‘%’);
}
if(temp[0] != 0)
printf(temp);
return i;
}
void main()
{
int i=10, j=20;
char buf[] = “This is a test”;
double f= 123.456;
mywrite(”String: %s\nInt: %d, %d\nFloat :%4.2f\nEnd”, buf, i, j, f, 0);
t(”aaa”, i);
}
//输出:
String: This is a test
Int: 10, 20
Float :123.46
End
当然这里的解析是不完善的。
c语言相关文章:c语言教程
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-33745-4.html
如果没蛆虫