Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.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_Apply - Fatal编程技术网

C:如何将变量序列应用于函数?

C:如何将变量序列应用于函数?,c,apply,C,Apply,在C语言中,有没有一种方法可以调用存储在数组中的参数的函数?我是C级新手,我甚至不确定这是否正确,但例如: void f0(int a) { ... }; void f1(int a, int b) { ... }; void f2(int a, int b, int c) { ... }; int array[5][2][?] = [ [&f0, [5]], [&f1, [-23, 5]], [&f2, [0, 1, 2]], [&am

在C语言中,有没有一种方法可以调用存储在数组中的参数的函数?我是C级新手,我甚至不确定这是否正确,但例如:

void f0(int a) { ... };
void f1(int a, int b) { ... };
void f2(int a, int b, int c) { ... };

int array[5][2][?] = [
    [&f0, [5]],
    [&f1, [-23, 5]],
    [&f2, [0, 1, 2]],
    [&f2, [1235, 111, 4234]],
    [&f0, [22]]
];

int i;
for (i = 0; i < 5; i++) {
    APPLY?(array[i][0], array[i][1])
}
不,不

在C中,更好的方法是将函数定义为所有函数都具有相同的签名,如:

void f0(int size, int elements[])
然后将适当大小的数组传递给函数

// this is a function pointer
void (*x)(int, int[]); 
...
// set x to point at f0
x = f0;
// call x (ie: f0) with 1 element from position 5 of array
x(1, &(array[5]));

在C中可能会有变量arity函数,但机制很笨拙,并且有一定的限制,即必须至少有一个固定参数,并且您需要能够从固定参数或变量参数本身判断变量列表的末尾在哪里

一个更典型的解决方案是这样一个例子,它利用了C的优点而不是缺点。(使用函数指针更新。)

#包括
无效f1(int,int*);
空f2(int,int*);
结构boxofits{
无效(*f)(整数,整数*);
int有多少个;
整数[4];
}intMachine[]={
{f1,1,{5,},
{f2,2,{-23,5},
{f1,3,{0,1,2},
{f2,3,{1235,111,4234},
{f1,1,{22,},
{ 0 }
};
无效派送(作废)
{
对于(结构BoxOfInts*p=intMachine;p->f;++p)
(*p->f)(p->多少,p->数字);
}
无效f1(整数个数,整数*p)
{
while(多少-->0){
int t=*p++;
printf(“f1%d%d\n”,数量,t);
}
}
空f2(整数有多少,整数*p)
{
while(多少-->0){
int t=*p++;
printf(“f2%d%d\n”,数量,t);
}
}
int main()
{
分派();
返回0;
}

我想也许你只是想:

array[i][0](array[i][1]);
在C中,从函数指针调用函数只需要函数调用操作符,即括号


可能有用的链接:

c没有列表的内置概念,或者,您必须在数组上设置显式循环,并且必须自己支持列表的长度

是的,这比python的方式更冗长,但这是因为python正在为您处理细节

非常适合处理概念性“列表”的数据结构:

  • 动态数组(可能包装在一个数组中,以便在同一位置保存元信息,如当前长度和分配的长度)
如果选择基于阵列的解决方案,则需要

  • 跟踪当前长度并将其传递给处理函数
  • 使用sentinel来标记数据的结束(这可能意味着使用更大的数据类型来允许您指定无法在数据中显示的sentinel)

  • 链表可以逐点处理,因为它有一个自然的结尾。

    这是最好的解决方案,先传递数组的大小,然后传递实际数组。我不确定我是否理解:我应该将项目的长度添加到数组中。好啊但是我如何调用以项为参数的函数呢?请看答案的最后一行。这就是调用f0,将1(表示arg的数量)加上指向数组中第五个位置的指针传递给它。实际上,我可能会将“array”变成一个结构数组(而不是一个3D数组),其中每个结构都有3个字段:函数、参数数量和参数数组。然后在循环中说
    (数组[i].f)(数组[i].n,数组[i].args)
    。顶部的{}是什么?可变长度数组?另外,我想调用各种f-s(f0、f1、f2),如何将它们添加到数组中,并在dispatch中调用适当的一个?还要注意,stdarg.h不允许构建任意参数数组,只允许复制已经存在的数组。您仍然需要在汇编中进行编组,或者通过大量的辅助函数a-la Glib/Gtk进行编组。
    {}
    语法定义了一个*初始值设定项列表',这些有时是可选的组会在给定聚合元素的列表完成时通知编译器。我不知道你想要不同的函数是因为算术以外的原因。我把它们放在修改后的示例中,这很有趣。参数应该以什么格式存储?我的意思是,调用函数f(inta,intb)可以写:int[]a=[1,2];void*指针=&f*指针(a)?我完全迷路了……这是个好问题。您不需要使用“指针(a)”--取消引用是隐含的,因此您不需要“”而只需要“指针(a)”。以这种方式调用函数时,参数的类型检查不能在编译时完成。由相关函数共享的“typedef”将对此有所帮助。函数指针部分末尾的链接中有更多信息,就在“字符串(以及为什么没有这样的东西)”部分之前。可能有一种更简单的方法来实现您的目标,您想做什么?以及您在数据等方面的局限性是什么?这可能可以通过
    varargs
    来实现,我将不做任何解释。您可以使用struct。以下是有关structs(简单对象)struct shape{int numberOfPoints;int points[4]的一些信息;char shapeType[10];}您可以将形状类型存储在shapeType字符串中,并将点存储在点数组中,然后将每个索引传递给函数以绘制点。
    #include <stdio.h> 
    
    void f0(int a              ){ printf("f0(%i)\n",      a    ); }
    void f1(int a, int b       ){ printf("f1(%i,%i)\n",   a,b  ); }
    void f2(int a, int b, int c){ printf("f2(%i,%i,%i)\n",a,b,c); }
    
    typedef void (*f_arg1)(int);
    typedef void (*f_arg2)(int,int);
    typedef void (*f_arg3)(int,int,int);
    
    struct fn_call {
      f_arg1 fn;
      int arg_num;
      int *args;
    } array[] = {  { (f_arg1)f0, 1, (int[]){5}               },
                   { (f_arg1)f1, 2, (int[]){-23, 5}          },
                   { (f_arg1)f2, 3, (int[]){0, 1, 2}         },
                   { (f_arg1)f2, 3, (int[]){1235, 111, 4234} },
                   { (f_arg1)f0, 1, (int[]){22}              }   };
    
    void apply( struct fn_call *call ){
      switch( call->arg_num ){
      case 1: ((f_arg1)call->fn)( call->args[0] );                  break;
      case 2: ((f_arg2)call->fn)( call->args[0], call->args[1] );   break;
      case 3: ((f_arg3)call->fn)( call->args[0], call->args[1], call->args[2] );
      }
    }
    
    int main(){
      for(unsigned i=0; i<sizeof(array); i++)  apply( &array[i] );
    }
    
    array[i][0](array[i][1]);
    
    #include <stdio.h> 
    
    void f0(int a              ){ printf("f0(%i)\n",      a    ); }
    void f1(int a, int b       ){ printf("f1(%i,%i)\n",   a,b  ); }
    void f2(int a, int b, int c){ printf("f2(%i,%i,%i)\n",a,b,c); }
    
    typedef void (*f_arg1)(int);
    typedef void (*f_arg2)(int,int);
    typedef void (*f_arg3)(int,int,int);
    
    struct fn_call {
      f_arg1 fn;
      int arg_num;
      int *args;
    } array[] = {  { (f_arg1)f0, 1, (int[]){5}               },
                   { (f_arg1)f1, 2, (int[]){-23, 5}          },
                   { (f_arg1)f2, 3, (int[]){0, 1, 2}         },
                   { (f_arg1)f2, 3, (int[]){1235, 111, 4234} },
                   { (f_arg1)f0, 1, (int[]){22}              }   };
    
    void apply( struct fn_call *call ){
      switch( call->arg_num ){
      case 1: ((f_arg1)call->fn)( call->args[0] );                  break;
      case 2: ((f_arg2)call->fn)( call->args[0], call->args[1] );   break;
      case 3: ((f_arg3)call->fn)( call->args[0], call->args[1], call->args[2] );
      }
    }
    
    int main(){
      for(unsigned i=0; i<sizeof(array); i++)  apply( &array[i] );
    }
    
    f0(5)
    f1(-23,5)
    f2(0,1,2)
    f2(1235,111,4234)
    f0(22)