在纯C中,如何将可变数量的参数传递给函数?

时间:2010-06-12 16:10:51

标签: c function

如何使用C而不是c ++,将变量参数传递(并访问)到函数中?

void foo(char* mandatory_param, char* optional_param, char* optional_param2...)

感谢

/ fmsf

6 个答案:

答案 0 :(得分:12)

使用stdarg.h

您需要使用va_list,然后使用宏va_startva_argva_end

有关详细信息,请参阅http://www.acm.uiuc.edu/webmonkeys/book/c_guide/2.10.html

答案 1 :(得分:9)

听起来你正在寻找varargs

#include <stdarg.h>
void foo(const char *fmt, ...)
{
  va_list argp;
  va_start(argp, fmt);
  int i = va_arg(argp, int);
  // Do stuff...
  va_end(argp);
}

答案 2 :(得分:7)

答案 3 :(得分:1)

在不直接支持可选参数的语言中,有几种方法可以实现类似的效果。我将按照从最不通用到最多的顺序列出它们:

  1. 创建同一功能的多个重载。我记得,你不能用C语言做到这一点。

  2. 使用可变参数函数。只需Google:http://www.google.com/search?q=variadic+function+c

  3. 我建议这样做:创建一个“params”或“args”类(或C语言中的结构),如下所示:

  4. // untested C code
    struct FooArgs {
        char * mandatory_param;
        char * optional_param;
        char * optional_param2;
        // add other params here;
    };
    

    然后让你的方法调用接受一个参数:

    // untested
    void foo(struct fooArgs * args)
    

    这样,随着需求的变化,您可以参数添加到fooArgs而不会破坏任何内容。

答案 4 :(得分:1)

#include <stdarg.h>

void do_sth (int foo, ...)
{
    int baz = 7;             /* "baz" argument */
    const char *xyz = "xyz"; /* "xyz" argument */

    /* Parse named parameters */
    va_list ap;
    va_start (ap, foo);
    for (;;) {
        const char *key = va_arg (ap, char *);
        if (key == NULL) {
            /* Terminator */
            break;
        } else if (strcmp (key, "baz") == 0) {
            baz = va_arg (ap, int);
        } else if (strcmp (key, "xyz") == 0) {
            xyz = va_arg (ap, char *);
        } else {
            /* Handle error */
        }
    }
    va_end (ap);

    /* do something useful */
}

do_sth (1, NULL);                             // no named parameters
do_sth (2, "baz", 12, NULL);                  // baz = 12
do_sth (3, "xyz", "foobaz", NULL);            // xyz = "foobaz"
do_sth (4, "baz", 12, "xyz", "foobaz", NULL); // baz = 12, xyz = "foobaz"

Variadic functions and arguments assignment in C/C++

答案 5 :(得分:0)

我有一个不在纯C语言中使用VA_LIST的解决方案。但是,它只能在32位上工作。在这里,发生的情况是调用堆栈的每个参数根据其类型占用了多个字节。可以创建一个大小大于4或8个字节的结构,因此只需对齐此结构中的所有参数即可。

int printf(void*,...);

typedef struct{
  char p[1024];
}P_CALL;

int soma(int a,int b){
  return a+b;
}

void main(){
  P_CALL
    call;
  char
    *pcall=(void*)&call;
  int
    (*f)()=soma,
    res;

  *(int*)pcall=1;
  pcall+=sizeof(void*);
  *(int*)pcall=2;
  pcall+=sizeof(void*);

  res=f(call);
  printf("%d\n",res);//3
}