如何工作vararg函数调用

时间:2014-01-03 10:44:54

标签: c variadic-functions

我试图了解可变参数函数是如何工作的。我读了man stdarg,我写了下面的代码:

#include <stdarg.h>
#include <stdio.h>

int sum(int count, ...){
    va_list lst;
    va_start(lst, count);
    printf("First=%i,Second=%i,Third=%i, Fourth=%i, Fifth=%i\n",va_arg(lst,int),va_arg(lst,int),va_arg(lst,int),va_arg(lst,int),va_arg(lst,int));
}

int main(){
    sum(1,2,3,4);
}

编译并运行后,我有以下输入:

First=0,Second=134513840,Third=4, Fourth=3, Fifth=2

我不明白这一点。我期望First=2, Second=3, Third=4和Fourth / Fifth具有未定义的值,因为在函数调用之后,参数从右向左推送到堆栈,而va_arg(lst, int)只返回指向堆栈中更深层的元素的指针。 / p>

2 个答案:

答案 0 :(得分:4)

有一些小错误(第一个是我在评论中暗示的):

  • 函数参数(此处为printf())按任何顺序(不一定是从左到右)的顺序进行计算。您必须首先将va_arg调用存储在变量或数组中,以便为程序添加序列点。
  • 在第一个参数中,您承诺提供args count的数量,但没有给出。
  • 承诺返回int
  • 的函数

像这样:

#include <stdarg.h>
#include <stdio.h>
int sum(int count, ...){
    if(count!=5) { printf("this version expects 5 variable args"); return 1; }
    va_list lst;
    va_start(lst, count);
    int a1 = va_arg(lst,int);
    int a2 = va_arg(lst,int);
    int a3 = va_arg(lst,int);
    int a4 = va_arg(lst,int);
    int a5 = va_arg(lst,int);
    va_end(lst); // added for cleanup
    printf("First=%i,Second=%i,Third=%i, Fourth=%i, Fifth=%i\n", 
         a1, a2, a3, a4, a5);
    return 0;
}
int main(){
    sum(5, 1,2,3,4,5);
    return 0;
}
    // prints: First=1,Second=2,Third=3, Fourth=4, Fifth=5

请注意,您的程序期望变量参数的数量为5,但var-arg-functions的目的通常是使参数的数量可变,您可以写:

#include <stdarg.h>
#include <stdio.h>
int sum(int count, ...){
    va_list lst;
    va_start(lst, count);
    int i=0; for(; i<count; ++i) {
        printf("at %i is %i\n", i, va_arg(lst, int));
    }
    va_end(lst);
    return 0;
}
int main(){
    sum(5, 1,2,3,4,5);
    return 0;
}

答案 1 :(得分:0)

这应该产生所需的解决方案。

#include <stdarg.h>
#include <stdio.h>

int sum(int count, ...){
    va_list lst;
    va_start(lst, count);
    int first=va_arg(lst,int),second=va_arg(lst,int),third=va_arg(lst,int),fourth=va_arg(lst,int),fifth=va_arg(lst,int);
    printf("First=%i,Second=%i,Third=%i, Fourth=%i, Fifth=%i\n",first,second,third,fourth,fifth);
}

int main(){
    sum(5,1,2,3,4,5);
}