Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 能否将函数参数的结构传递给函数?_C - Fatal编程技术网

C 能否将函数参数的结构传递给函数?

C 能否将函数参数的结构传递给函数?,c,C,我正在使用一个第三方库(其中的代码我无法编辑!),它有一个接受大量参数的函数。使用它看起来有点像这样: void func(int a, int b, int c, int d, int e) { //do something... } int main(void) { func(1, 2, 3, 4, 5); } 然而,它接受了这些论点,并立即抛弃它们。我想保留这些论点,并将其用于其他方面。我想做的是: void func(int a, int b, int c, int d, i

我正在使用一个第三方库(其中的代码我无法编辑!),它有一个接受大量参数的函数。使用它看起来有点像这样:

void func(int a, int b, int c, int d, int e) {
  //do something...
}

int main(void) {
  func(1, 2, 3, 4, 5);
}
然而,它接受了这些论点,并立即抛弃它们。我想保留这些论点,并将其用于其他方面。我想做的是:

void func(int a, int b, int c, int d, int e) {
  //do something...
}

typedef struct foo foo;
struct foo {
  int a;
  int b;
  int c;
  int d;
  int e;
};

foo bar = {1, 2, 3, 4, 5};

int main(void) {
  func(bar);
}
不幸的是,这会引发一个类型错误:

main.c:17:8: error: incompatible type for argument 1 of 'func'
   func(bar);
        ^~~
main.c:12:6: note: expected 'int' but argument is of type 'foo {aka struct foo}'
 void func(int a, int b, int c, int d, int e) {
      ^~~~
main.c:17:3: error: too few arguments to function 'func'
   func(bar);
   ^~~~

执行
func(条形图a、条形图b、条形图c、条形图d、条形图e)可以工作,但很冗长。我能做些什么魔术来绕过这个问题吗?同样,我不能修改库代码。

不,没有办法这样做。但是,如果您经常调用函数,那么将函数包装在您自己的函数中可能是值得的,这样您就可以将指向结构的指针作为参数传递,然后让您的函数通过不太优雅的参数方法调用实际的函数


值得一提的是,对于传递的每个参数,都会在堆栈上推送一个项,因此如果函数需要特定数量的参数,那么在二进制级别,它会在堆栈上推送许多参数。对于一个你无法控制的函数来说,这是无法改变的。

遗憾的是,没有什么好办法可以解决这个问题(至少,我所知道的都没有)。您是否考虑过编写宏来“解包”结构?比如:“定义解包(foo)foo.a,foo.b,foo.c,foo.d,foo.e”。然后可以执行“func(UNPACK(bar))”。更好的方法是使用静态内联包装函数,如
静态内联void funcwrap(struct foo args){func(args.a,args.b,args.c,args.d,args.e);}
。它与宏一样快,但只计算其参数一次,因此您可以安全地执行,例如
funcwrap(*(ptr++))如果
ptr
是指向参数结构数组的指针。(作为一个宏,它将增加
ptr
五倍。)参数传递给函数的方式是特定于平台的。并非所有平台都传递堆栈上的所有参数。例如,在ARM上,通常在寄存器中传递前4个参数,而在堆栈中只传递其他参数。这是针对非varargs函数的,varargs函数可以传递所有参数,但寄存器中的最后一个非变量参数和堆栈上的剩余参数除外。@Meixner很好,感谢您的澄清。即使在寄存器的情况下,这一点仍然成立。