复杂的C声明

Kau*_*eya 69 c c++ function-pointers declaration

我刚刚在互联网上查看了一些代码,发现了这个:

float * (*(*foo())[SIZE][SIZE])()
Run Code Online (Sandbox Code Playgroud)

我如何阅读此声明?是否有一套特定的规则来阅读这些复杂的声明?

Kos*_*Kos 119

我有一段时间没有这样做!

从开始foo向右走.

float * (*(*foo())[SIZE][SIZE])()

foo是一个没有参数的函数......

因为有一个右括号,所以不能正确.往左走:

float * (*(* foo())[SIZE][SIZE])()

foo是一个没有参数返回指针的函数

不能再往前走,所以让我们越过括号再向右走

float * (*(* foo())[SIZE][SIZE])() float * (*(* foo())[SIZE][SIZE])() float * (*(* foo())[SIZE][SIZE])()

foo是一个没有参数的函数,返回一个指向SIZE SIZE数组数组的指针...

到达结束括号,再次离开以达到指针符号:

float * (*(* foo())[SIZE][SIZE])()

foo是一个没有参数的函数,返回指向SIZE指针的SIZE数组数组的指针...

再次左括号,所以我们交叉它再次右转:

float *( *(* foo())[SIZE][SIZE])() float *( *(* foo())[SIZE][SIZE])()

foo是一个没有参数的函数,返回指向SIZE指针的SIZE数组数组的指针,指向没有参数的函数...

并留到最后

float * ( *(* foo())[SIZE][SIZE])()

foo是一个没有参数的函数,返回指向SIZE指针的SIZE数组数组的指针,该指针指向一个没有参数的函数,返回指向float的指针


无论是谁写的,请教他使用typedef:

// Function that returns a pointer to float
typedef float* PFloatFunc ();

// Array of pointers to PFloatFunc functions
typedef PFloatFunc* PFloatFuncArray2D[SIZE][SIZE];

// Function that returns a pointer to a PFloatFuncArray2D
PFloatFuncArray2D* foo();
Run Code Online (Sandbox Code Playgroud)

  • 为"和谁写了那个,请教他使用typedef"+1 (57认同)
  • 请注意,'无参数'部分仅适用于C++; 对于C,它表示"未指定的参数列表"(但它不能是可变参数函数,因为它们必须在范围内具有完整的原型,即使在C中). (2认同)

Joh*_*ode 99

标准规则:找到最左边的标识符并解决问题,记住[]()绑定之前*:

            foo                      -- foo
            foo()                    -- is a function
           *foo()                    -- returning a pointer
          (*foo())[SIZE]             -- to a SIZE-element array
          (*foo())[SIZE][SIZE]       -- of SIZE-element arrays
         *(*foo())[SIZE][SIZE]       -- of pointers
        (*(*foo())[SIZE][SIZE])()    -- to functions
      * (*(*foo())[SIZE][SIZE])()    -- returning pointers
float * (*(*foo())[SIZE][SIZE])();   -- to float
Run Code Online (Sandbox Code Playgroud)

所以假设你有一堆函数返回指针float:

float *quux();
float *bar();
float *bletch();
float *blurga();
Run Code Online (Sandbox Code Playgroud)

假设您想将它们存储在2x2表中:

float *(*tab[SIZE][SIZE])() = {quux, bar, bletch, blurga};
Run Code Online (Sandbox Code Playgroud)

tab是指向返回指针的函数的SIZE x SIZE指针数组float.

现在让我们决定我们想要一个函数来返回指向该表的指针:

float *(*(*foo())[SIZE][SIZE])()
{
  static float *(*tab[SIZE][SIZE])() = {quux, bar, bletch, blurga};
  return &tab;
}
Run Code Online (Sandbox Code Playgroud)

请注意,您可以使用多个函数来构建不同函数的表,或者以不同方式组织相同的函数:

float *(*(*qwerbl())[SIZE][SIZE])()
{
  static float *(*tab[SIZE][SIZE])() = {blurga, bletch, bar, quux};
  return tab;
}
Run Code Online (Sandbox Code Playgroud)

这是我能想到做这样的事情的唯一原因.你不应该经常在野外看到这样的类型(尽管它们偶尔会突然出现,而且我也写了类似令人发指的东西).


Cle*_* J. 6

根据cdecl.org

声明foo为函数返回指向数组的数组SIZE指向函数返回指向float的指针的SIZE指针

如果您想手动解码,请使用Luchian Grigore给出的螺旋规则.