c语言传递变长参数

现在假设我有一个变长参数函数sum : int sum(int n, ...) 实现n个数的相加,我还有一个函数sumplus : int sumplus(int n, ...); 在第二个函数中我需要这样调用sum : sum(n+3, 1, 2, 3, ...),也就是将函数sumplus的变长参数传给sum,我应该怎么实现呢?
一份错误的代码:

#include <stdio.h>
#include <stdarg.h>
void vprint(int n, va_list vl)
{
int i;
for(i=0; i<n; i++)
printf("%d, ", va_arg(vl, int));
printf("\n");
}
void print(int n, ...)
{
va_list vl;
va_start(vl, n);
vprint(n, vl);
va_end(vl);
}
void print2(int n, int a, ...)
{
va_list vl;
va_start(vl, n);//使用倒数第二个有名变量
vprint(n+1, vl);
va_end(vl);
}
int main()
{
print(3, 1, 2, 3);
print(4, 0, 2, 3, 1);
print2(3, 100, 1, 2, 3);//输出1 2 3 0
return 0;
}

按照你现在给出的代码,
print2(3, 100, 1, 2, 3);

输出的是1 2 3加上一位不确定值
因为va_start(vl, n);这一步理论上可以得到以a开头的va_list指针,但实际上由于编译器优化,它的效果和va_start(vl, a);是相同的

这一点,你可以打印出指针地址来确定一下

从你的代码推测,你是想让print2打印出后四个参数,包括a在内
即 100 1 2 3
如果是这样 可以用另一种方式做到

print2中,不要调用va_start
而是直接 vl=&a;

如下
void print2(int n, int a, ...)
{
va_list vl;
// va_start(vl, n);//使用倒数第二个有名变量

vl = &a;//编译器想优化 不让。 直接强势插入
vprint(n+1, vl);

va_end(vl);
}
可以试一下是否是你需要的效果。 如果不是 再追问追问

谢谢回答,跟我昨晚躺床上想的一样,不过实际的函数调用中对参数做了一些处理,va_list这些宏应该是获得实参在栈中的地址, '...'编译器是如何处理的还不清楚,不过应该没有很好的解决方案了,大概只能重写了吧

追答

从stdarg中定义的模式来看,用va_start从n开始,应该是可以得到从a开始的参数列表的
不过在编译的时候 我的编译器给了一个warning
second parameter of 'va_start' not last named argument
从这个信息上看,编译器对va_start调用的时候是做了检查的
从运行结果上看
用va_start(vl, n)和va_start(vl, a)得到的vl地址是相同的

&n=0xbff54640 &a=0xbff54644 vl=0xbff54648
所以猜测是编译器给优化了,即不论va_start的第二个参数传过去什么,都是变参的起始地址
所以才改用强势插入的方式

想知道你要达成的效果是什么?这样的方式是否可以?
或许有更好的方法

追问

应该没什么办法了,我要做的是这样的函数funA(int n, ...);
funB(int a, int b, int n, ...)
{
int c = ...
int d = ....
funA(n+2, c, d, ...); //

}

追答

直接传可变参数 似乎C没有什么很好的处理方案
用va_list做参数,然后传递似乎是一个方式,不过也不觉得好

其实按照你要求的用全int不定长度参数,最好的方式应该是用int *型
传不定长度数组
容量动态分配,并在使用后释放
可以传两个参数 int size, int * p
也可以只传一个参数 int *,把size放在第一个元素中

当需要扩充时,重新申请内存或者用realloc
比可变参更容易理解设计以及维护

追问

我还是完整实现一下funB吧.代码也不算长

温馨提示:答案为网友推荐,仅供参考
第1个回答  2013-09-30
这个在c++中叫重载,每个不定的参数个数的函数名字可以相同,系统根据参数的类型、个数会自动调用相应的函数来进行编译
这不同的参数类型、个数的子函数需要都写好

这个在重载中有详细的介绍,你可以看看追问

好像你没有理解我的意思

第2个回答  推荐于2017-10-09
C语言中有一种长度不确定的参数,形如:"…",它主要用在参数个数不确定的函数中,我们最容易想到的例子是printf函数。
下面举个例子
  原型:

  int printf( const char *format [, argument]... );

  使用例:

  printf("Enjoy yourself everyday!\n");

  printf("The value is %d!\n", value);

  这种可变参数可以说是C语言一个比较难理解的部分,这里会由几个问题引发一些对它的分析。

  注意:在C++中有函数重载(overload)可以用来区别不同函数参数的调用,但它还是不能表示任意数量的函数参数。
相似回答