我写了一段代码:
void xy(int a,...)
{
va_list list;
va_start(list,a);
int result=0;//va_start(list,x);
for(;;)
{
int p=va_arg(list,int);
cout<<p<<endl;
if(p==0)
break;
result+=p;
}
va_end(list);
cout<<result<<endl;
}
并调用此函数: XY(20,30,40);
我预计将会打印20,30,40。和他们的总和。但它正在打印:
30 40 13336564 11872144 -3271312 -3271224 12029596 11926688 134527888 -3271224 12029596 1 -3271180 -3271172 11929640 0 191296075
不知道为什么。
请提出一些解决方案。
答案 0 :(得分:1)
嗯,你的代码真的很聪明,不是吗?您正在检查零以标记参数列表的结尾。但是,您使用参数列表调用该函数,该参数列表不以零结尾或包含零。您认为零点来自您正在检查的位置?改为打电话
xy (20, 30, 40, 0);
bluebell的评论显然是无稽之谈。没有办法检测到没有更多的论据。调用者和被调用者必须同意如何检测参数列表的结尾,然后调用者当然必须发送写参数。
printf通过调用者发送printf函数将检查的格式字符串来完成此操作。或者您可以将参数的数量作为第一个参数发送,因此计算n个值的平均值的函数可以被称为
average (1, 3.7);
average (3, 3.7, 4.1, 4.2);
20未打印,因为20作为命名参数发送,因此您的总和应以值a开头。通过va_arg宏接收30和40,如果你将它作为参数传递,它将是数字0 - 如果你没有传递该数字,你的代码将继续从随机存储器位置读取数据,直到它读取包含的内存为止数字0。
另一个例子:当你调用printf时(“%d%d \ n”,4,5); printf函数获取格式字符串“%d%d \ n”作为第一个参数。它检查此字符串并找到两次字母%d,因此这意味着必须有两个int参数。如果您没有提供两个int参数,则可能会打印出垃圾。