在纯C语言中,如何将数量可变的参数传递到函数中? 我如何通过C,而不是C++,将变量参数转换成函数? void foo(char* mandatory_param, char* optional_param, char* optional_param2...)
谢谢 /fmsf使用标准h 您需要使用va_list,然后使用宏va_start、va_arg和va_end 有关更多信息,请参见使用标准.h 您需要使用va_list,然后使用宏va_start、va_arg和va_end在纯C语言中,如何将数量可变的参数传递到函数中? 我如何通过C,而不是C++,将变量参数转换成函数? void foo(char* mandatory_param, char* optional_param, char* optional_param2...),c,function,C,Function,谢谢 /fmsf使用标准h 您需要使用va_list,然后使用宏va_start、va_arg和va_end 有关更多信息,请参见使用标准.h 您需要使用va_list,然后使用宏va_start、va_arg和va_end 有关更多信息,请参见听起来您正在寻找 听起来你在找我 阅读关于阅读关于在不直接支持可选参数的语言中,有几种方法可以实现类似的效果。我将按功能最少到最多的顺序列出: 创建同一函数的多个重载。我记得,在C语言中不能这样做 使用可变函数。只需谷歌一下: 我建议这样做:在C中创建一
有关更多信息,请参见听起来您正在寻找
听起来你在找我
阅读关于阅读关于在不直接支持可选参数的语言中,有几种方法可以实现类似的效果。我将按功能最少到最多的顺序列出: 创建同一函数的多个重载。我记得,在C语言中不能这样做 使用可变函数。只需谷歌一下: 我建议这样做:在C中创建一个params或args类或结构,如下所示: 然后使方法调用接受单个参数:
// untested
void foo(struct fooArgs * args)
这样,随着需要的变化,您可以在不破坏任何内容的情况下向fooArgs添加参数。在一种不直接支持可选参数的语言中,有几种方法可以实现类似的效果。我将按功能最少到最多的顺序列出:
#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语言中不能这样做
使用可变函数。只需谷歌一下:
我建议这样做:在C中创建一个params或args类或结构,如下所示:
然后使方法调用接受单个参数:
// untested
void foo(struct fooArgs * args)
这样,随着需求的变化,您可以在不破坏任何内容的情况下向fooArgs添加参数
#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中不使用VA_列表。但是,它只在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
}
我有一个解决方案,在纯C中不使用VA_列表。但是,它只在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
}
我想你指的是可变数量的参数。@mathepic:ty修复了这个问题我想你指的是可变数量的参数。@mathepic:ty修复了这个问题,可能是因为你所做的只是提供了一个链接,而不是将一些答案放在这里,并提供了一个外部参考以获取更多信息。提供了一个有用的,直接相关链接不应被视为否决投票的理由。使用链接+1。为什么要复制已经存在的东西?为什么要总结已经明确的内容呢?可能是因为他的答案在其他两个得票较高的人的1-2分钟内发布,而在提问的6分钟内发布。让我们看看,对于正确答案的质量,我们有多挑剔和忘恩负义-可能是因为你所做的只是提供了一个链接,而不是把一些答案放在这里,并提供了一个外部参考以获取更多信息。提供一个有用的、直接相关的链接不应被视为否决投票的理由。使用链接+1。为什么要复制已经存在的东西?为什么要总结已经明确的内容呢?可能是因为他的答案在其他两个得票较高的人的1-2分钟内发布,而在提问的6分钟内发布。让我们看看,对于正确答案的质量,我们有多挑剔和忘恩负义-PIt可能有助于读取示例中的多个参数,并显示使用sentinel停止,因为这与大多数语言不同。PIt可能有助于读取示例中的多个参数,并显示使用sentinel停止,因为这与大多数应为void的语言foostruct FooArgs*args不同,但是大多数人可能会在结构上使用typedef来简化事情。可能是因为问题在你的答案发布之前就已经澄清了,请注意,要询问传递可变数量的参数,而不是可选参数。你可能会考虑修改你的问题或移除它。+ 1的思考。并不是因为OP提出了一个非常具体的问题,所以用另一种方法解决类似问题的答案是不好的。Apollo的答案很有趣,甚至可以在调用链中使用。这应该是void foostruct FooArgs*args,但大多数人可能会在结构上使用typedef来简化事情。可能是因为在发布答案之前,问题已经澄清了,请注意,要询问传递可变数量的参数,而不是可选参数。你可能会考虑修改你的问题或移除它。+ 1的思考。并不是因为OP提出了一个非常具体的问题
用另一种方法解决类似问题的答案是不好的。Apollo的答案很有趣,甚至可以在调用链中使用。如果你打算否决投票,至少在评论中说为什么,而不是让我去想为什么我的答案在某些方面可能是错误的。哦,天哪,程序员有一种方法会使用varargs犯错误!他们一定很可怕!如果你要投否决票,至少在评论中说为什么,而不是让我去想为什么我的答案在某些方面可能是不正确的。哦,天哪,程序员有一种使用varargs犯错误的方法!他们一定很可怕!