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

C 定义函数指针数组的正确方法是什么?

C 定义函数指针数组的正确方法是什么?,c,arrays,function-pointers,C,Arrays,Function Pointers,假设我有一个函数指针数组。换句话说,我可能希望调用这样的矩阵转置函数,具体取决于我的矩阵的数据类型: Transp[dtype][index_dtype](A.ia, A.a, B.ia, B.a); Transp中的函数可能如下所示: void transp_i64_i8(const int64_t* ia, const int8_t* a, int64_t* ib, int8_t* b) { // transpose here return; } 除了改变指针类型 在我看来,我应

假设我有一个函数指针数组。换句话说,我可能希望调用这样的矩阵转置函数,具体取决于我的矩阵的数据类型:

Transp[dtype][index_dtype](A.ia, A.a, B.ia, B.a);
Transp中的函数可能如下所示:

void transp_i64_i8(const int64_t* ia, const int8_t* a, int64_t* ib, int8_t* b) {
  // transpose here
  return;
}
除了改变指针类型

在我看来,我应该这样声明我的函数指针数组:

void (**Transp)(const void* ia, const void* a, const void* ib, const void* b)[DTYPES_MAX][INDEX_TYPES_MAX] = {
  {transp_i8_i8, transp_i8_i16, transp_i8_i32, /* ... */ },
  {transp_i16_i8, transp_i16_i16, /* ... */ },
  {transp_i32_i8, transp_i32_i16, /* ... */ },
  /* ... */
}
不幸的是,这似乎不起作用:

error: called object ‘Transp[(int)self_m->storage->dtype][(int)((struct YALE_STORAGE *)self_m->storage)->index_dtype]’ is not a function
../../../../ext/nmatrix/nmatrix.c: In function ‘nm_complex_conjugate_bang’:
../../../../ext/nmatrix/nmatrix.c:1910:32: error: subscripted value is neither array nor pointer nor vector
我发现了,但我真的需要一个例子来理解和应用我的确切用例

那么,定义函数指针数组的正确方法是什么呢?具体来说,声明部分是如何编写的


我意识到使用typedef可以更容易地实现这一点,但我正在编写一个代码生成器,而不是使用typedef。

因此函数指针的类型是

ReturnType (*)(Args);
函数指针数组的类型为

ReturnType (*[n])(Args);
因此,函数指针数组的数组

ReturnType (*[n][m])(Args);
将其与现有的进行比较,看起来您将数组声明为

ReturnType (**)(Args)[n][m];
也就是说,指向返回数组数组的函数的指针。如果从变量声明中删除一个星号,并将数组移到括号内,我认为这将解决问题


希望这有帮助

因此函数指针的类型是

ReturnType (*)(Args);
函数指针数组的类型为

ReturnType (*[n])(Args);
因此,函数指针数组的数组

ReturnType (*[n][m])(Args);
将其与现有的进行比较,看起来您将数组声明为

ReturnType (**)(Args)[n][m];
也就是说,指向返回数组数组的函数的指针。如果从变量声明中删除一个星号,并将数组移到括号内,我认为这将解决问题


希望这有帮助

您声明它的方式与使用它的方式类似,例如:

void (*Transp[DTYPES_MAX][INDEX_TYPES_MAX])(const int64_t*,
                                            const int64_t*,
                                            const int64_t*,
                                            const int64_t*);

您以与使用方式类似的方式声明,例如:

void (*Transp[DTYPES_MAX][INDEX_TYPES_MAX])(const int64_t*,
                                            const int64_t*,
                                            const int64_t*,
                                            const int64_t*);

如果您的函数指针都有固定数量的参数,但参数数量或参数类型不同,则无论如何都不能使用单一类型的函数指针来表示所有函数指针


在POSIX系统中,可以使用void*数组的数组,因为POSIX保证函数指针的表示,void*是相同的。在C语言中,函数指针和void*之间实际上没有转换,但编译器通常支持它。

如果函数指针都有固定数量的参数,但参数数量或参数类型不同,无论如何,您都不能使用单一类型的函数指针来表示所有函数指针


在POSIX系统中,可以使用void*数组的数组,因为POSIX保证函数指针的表示,void*是相同的。在C语言中,函数指针和void*之间实际上没有转换,但编译器通常支持它。

为什么代码生成器不允许使用typedef?仅仅因为代码是自动生成的,并不意味着你不想不时地阅读它。为什么代码生成器不允许使用typedef?只是因为代码是自动生成的,并不意味着你不想时不时地读它。@ Mehrdad——我认为你不能在C或C++中声明一系列函数。你的ARG是在错误的地方,函数指针数组与指针指针的数组返回函数数组。@ CharlesBailey -我刚刚发现了。你能再检查一下这个修订版本是否正确吗?@templatetypedef:那么我想我错了。。。我知道你当然可以传递一个参数,所以我猜也许你可以传递它们的数组,但如果你不能,那就没关系了@Mehrdad -我认为你不能在C或C++中声明一系列函数。你的ARG是在错误的地方,函数指针数组和指针指向数组的函数返回数组。@ CharlesBailey -我刚刚发现了。你能再检查一下这个修订版本是否正确吗?@templatetypedef:那么我想我错了。。。我知道你当然可以传递一个参数,所以我猜也许你可以传递它们的数组,但如果你不能,那就没关系了@莫霍克:不,这是一个指向函数的指针数组。仅仅因为数组是二维的,并不意味着数组元素本身需要额外的间接寻址。@mohawkjohn:不,它是一个指向函数的指针数组数组。仅仅因为数组是二维的,并不意味着数组元素本身需要额外的间接寻址。