如何使用C而不是c ++,将变量参数传递(并访问)到函数中?
void foo(char* mandatory_param, char* optional_param, char* optional_param2...)
感谢
/ fmsf
答案 0 :(得分:12)
使用stdarg.h
您需要使用va_list
,然后使用宏va_start
,va_arg
和va_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)
在不直接支持可选参数的语言中,有几种方法可以实现类似的效果。我将按照从最不通用到最多的顺序列出它们:
创建同一功能的多个重载。我记得,你不能用C语言做到这一点。
使用可变参数函数。只需Google:http://www.google.com/search?q=variadic+function+c
我建议这样做:创建一个“params”或“args”类(或C语言中的结构),如下所示:
)
// 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"
答案 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
}