如何解构复杂的C/C++语句/声明?

dfty9e19  于 2023-05-06  发布在  C/C++
关注(0)|答案(2)|浏览(127)

以下面的代码片段为例。

char* const (*(* const bar)[5])(int)

似乎无法理解它,或者更严重的是,无法确定从哪里开始理解它的初始点。

dojqjjoe

dojqjjoe1#

让我们一步一步地考虑声明

char* const (*(* const bar)[5])(int);

这部分

* const bar

声明一个名为bar的常量指针,该指针指向一个指针类型的5个元素的数组

*(* const bar)[5]

指向函数类型的指针

char* const (int)

这是一个演示程序。

#include <stdio.h>

char * const f1( int n )
{
    printf( "f1 called with n = %d\n", n );

    return NULL;
}

char *const f2( int n )
{
    printf( "f2 called with n = %d\n", n );

    return NULL;
}

char *const f3( int n )
{
    printf( "f3 called with n = %d\n", n );

    return NULL;
}

char *const f4( int n )
{
    printf( "f4 called with n = %d\n", n );

    return NULL;
}

char *const f5( int n )
{
    printf( "f5 called with n = %d\n", n );

    return NULL;
}

int main( void )
{
    char *const ( *a[5] )( int ) = { f1, f2, f3, f4, f5 };

    for (int i = 0; i < 5; i++)
    {
        a[i]( i );
    }

    putchar( '\n' );

    char *const ( *( *const bar )[5] )( int ) = &a;

    for (int i = 0; i < 5; i++)
    {
        ( *bar )[i]( i );
    }

}

程序输出为

f1 called with n = 0
f2 called with n = 1
f3 called with n = 2
f4 called with n = 3
f5 called with n = 4

f1 called with n = 0
f2 called with n = 1
f3 called with n = 2
f4 called with n = 3
f5 called with n = 4

使用typedef声明可以使指针的声明更具可读性。

svdrlsy4

svdrlsy42#

“反映使用的声明”说:
表达式*(*(*bar)[0])(0)给出char
我们可以继续说:
表达式(*(*bar)[0])(0)给出了一个指向char的指针。
所以:
使用(int)参数调用函数(*(*bar)[0])将返回指向char的指针。...

解引用bar,则数组(大小为5)中的索引在具有(int)参数的函数上具有指针,将返回指向char的指针

表达式也可以从对象开始解码。在这里,我们以名称bar作为开始。但是在一些表达式中,我们没有任何名字,起点是第一个表达式(括号中),它的右边有一个数组[...]或一个函数调用(...)或什么都没有。请注意,要读取表达式,我们首先读取右边的部分(数组和函数),然后在左边完成读取第一部分,然后在左边完成其他部分(指针)。
1.查看开始表达式:(* const bar)bar是常量指针指向...
将表达式替换为bbar,得到char* const (* bbar[5])(int);
1.看上面的表情:(* bbar[5])bbar是一个5个指针的数组,指向...
将表达式替换为bbbar,得到char* const bbbar(int);
1.看上面的表情:char* const bbbar(int)bbbar是一个接收int并返回一个指向char的常量指针的函数。

bar是一个常量指针,指向一个5个指针的数组,指向接收(int)的函数,返回指向char的常量指针

在真实的中,我们永远不必这样做,复杂的表达式是typedef

typedef char* const (*  FunctionPtr)(int);
typedef FunctionPtr     ArrayOfFctPtr[5];
ArrayOfFctPtr* const    bar;

相关问题