【发布时间】:2010-06-12 16:10:50
【问题描述】:
如何使用 C 而不是 c++ 将可变参数传递(和访问)到函数中?
void foo(char* mandatory_param, char* optional_param, char* optional_param2...)
谢谢
/fmsf
【问题讨论】:
-
我假设您的意思是可变数量的参数。
-
@mathepic:你解决了这个问题
如何使用 C 而不是 c++ 将可变参数传递(和访问)到函数中?
void foo(char* mandatory_param, char* optional_param, char* optional_param2...)
谢谢
/fmsf
【问题讨论】:
使用stdarg.h
您需要使用va_list,然后使用宏va_start、va_arg 和va_end。
欲了解更多信息,请参阅http://www.acm.uiuc.edu/webmonkeys/book/c_guide/2.10.html
【讨论】:
听起来您正在寻找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);
}
【讨论】:
【讨论】:
#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"
【讨论】:
在不直接支持可选参数的语言中,有几种方法可以达到类似的效果。我将按照从最不通用到最多的顺序列出它们:
为同一函数创建多个重载。我记得,你不能在 C 中做到这一点。
使用可变参数函数。谷歌一下: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 而不会破坏任何东西。
【讨论】:
我有一个在纯 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
}
【讨论】: