1

假设我有一个函数指针数组。换句话说,我可能想像这样调用矩阵转置函数,具体取决于我的矩阵是什么 dtype:

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。)

4

3 回答 3

3

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

void (*Transp[DTYPES_MAX][INDEX_TYPES_MAX])(const int64_t*,
                                            const int64_t*,
                                            const int64_t*,
                                            const int64_t*);
于 2012-06-15T21:13:00.120 回答
2

所以函数指针的类型是

ReturnType (*)(Args);

函数指针数组的类型是

ReturnType (*[n])(Args);

所以函数指针数组的数组将是

ReturnType (*[n][m])(Args);

将此与您所拥有的进行比较,看起来您将数组声明为

ReturnType (**)(Args)[n][m];

即,指向返回数组数组的函数的指针。如果您从变量声明中删除其中一颗星并将数组移动到括号内,我认为这将解决问题。

希望这可以帮助!

于 2012-06-15T21:11:47.250 回答
0

If your function pointers all have a fixed number of parameters but different number of parameters or different parameter types, you cannot anyway portably use a single type of function pointers to represent all the function pointers.

In POSIX system you can use an array of array of void * as POSIX guarantees the representation of function pointers and void * is the same. In C actually there is no conversion between function pointers and void * but compilers usually support it.

于 2012-06-15T21:20:03.477 回答