复杂的C声明(Complex C declaration)

2019-07-20 14:53发布

我只是通过一些代码会在互联网上,发现这一点:

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

如何解读这一声明? 是否有读这样复杂的声明一组特定的规则?

Answer 1:

我还没有在一段时间做到了这一点!

先从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数组的数组,以不带参数的函数返回一个指针浮动的功能


无论谁写的,请教他用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();


Answer 2:

标准规则:找到最左边的标识和工作的方式了,记住, []()绑定之前*

            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

所以,想象一下你有一大堆的返回函数指针float

float *quux();
float *bar();
float *bletch();
float *blurga();

比方说,你想将它们存储在一个2x2的表:

float *(*tab[SIZE][SIZE])() = {quux, bar, bletch, blurga};

tab是指针的大小x SIZE数组返回函数指针float

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

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

需要注意的是,你可以有一个建立不同的功能表多种功能,或者不同的方式组织相同的功能:

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

这是我能想到的这样做的唯一原因。 你不应该看到的类型像这样在野外经常(虽然他们突然出现偶尔的,我一直在内疚写一些类似的令人发指的)。



Answer 3:

据cdecl.org

声明FOO作为函数返回指针的指针阵列大小的阵列大小的功能返回指针到浮

使用,如果你想用手工将其解码由Luchian格里戈里给出的螺旋规律。



Answer 4:

在这里做的最好的事情是转换成一系列的类型定义的。

typedef float * fnReturningPointerToFloat();
typedef fnReturningPointerToFloat* fnArray[SIZE][SIZE];
fnArray* foo();


Answer 5:

一般情况下,你可以尝试cdecl.org但你需要替换SIZE

假设你换SIZE 12,你会得到:

声明FOO作为函数返回指针的指针阵列12的阵列12的功能在返回指针到浮

我不知道那确实能帮助你!

两个观察这里:

  1. 我猜,这个代码没有它解释什么它的目的是旁边的注释(即不的技术解释它是什么,但它是什么,从功能/商业的角度实现)如果程序员需要使用东西,因为这是复杂的,他们应该是很好的解释将来的维护什么目的服务。
  2. 当然,在C ++中有实现同样的事情更明显,可能更安全的方式。


Answer 6:

本文gaves我,任何C如何轻松地准备申报最好的线索:

http://c-faq.com/decl/spiral.anderson.html

有三个简单的步骤如下:

  • 与未知元素开始,移动螺旋/顺时针方向; ecountering以下元素在与对应的英文语句替换它们:

    • [X][] =>的数组... X规格或数组的大小未定义...

    • (type1, type2) =>功能通过Type1和Type2返回...

    • * =>指针(多个)...

  • 保持,直到所有令牌已经覆盖螺旋/顺时针方向做这个。

  • 总是先解决在括号任何东西!

例如:

             +-------+
             | +-+   |
             | ^ |   |
        char *str[10];
         ^   ^   |   |
         |   +---+   |
         +-----------+

Question we ask ourselves: What is str?

``str is an...

- We move in a spiral clockwise direction starting with `str' and the first character we see is a `[' so, that means we have an array, so...
  ``str is an array 10 of...

- Continue in a spiral clockwise direction, and the next thing we encounter is the `*' so, that means we have pointers, so...
  ``str is an array 10 of pointers to...

- Continue in a spiral direction and we see the end of the line (the `;'), so keep going and we get to the type `char', so...
``str is an array 10 of pointers to char''

We have now ``visited'' every token; therefore we are done!


Answer 7:

从http://cdecl.org/

声明FOO作为函数返回指针的指针阵列大小的阵列大小的功能返回指针到浮



文章来源: Complex C declaration