C指针复杂声明

发布于 2022-09-03 08:52:58 字数 118 浏览 14 评论 0

char (*(*x())[])();

char (*(*x[3])())[5];

请描述一下上面的两个指针的含义,如果能写两个实例的话,就更好了。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

行雁书 2022-09-10 08:52:58

对于这种复杂的声明格式,可以采用替换的形式来看明白。

比如char (*(*x())[])();这个, 你可以找个 a代替括号里面的,然后逐步代替。

char (*(*x())[])();
// 用a 代替 (*x())[]
char (*a)();
// 上面的a的意思就是一个函数指针,空参,返回char
// 再看(*x())[],用b代替 *x()
(b)[];
// b是一个数组,而且数组每一项是一个指针a
*x();
// x是一个空参函数,返回类型是一个b的指针

所以上面的x是一个函数,参数为空,返回值是一个数组的指针,数组的每一项是一个指针,指向的是一个函数指针,这个函数的形式是空参返回char。

所以使用的方式就是

char f1(){return 1;};
char f2(){return 2;};

char (*(*x())[2])(){
    typedef char A();
    
    A* f = f1;
    
    typedef A* B[];
    
    B arr = {f,f};
    
    typedef B* F();
    
    return &arr;    
};

同样的道理
char (*(*x[3])())[5];这个表达式的使用方式就是

typedef char A[5];

A* b(){
    static A a = {1,2,3,4,5};
    return &a;
}

typedef A* B();

char (*(*x[3])())[5] = {&b,&b,&b};

也就是说x 是个有3个值的数组,每个数组的类型是一个函数指针,这个函数(b)是空参,返回的是一个指针,指向一个含有5个char的数组。

彩扇题诗 2022-09-10 08:52:58
char (*(*x())[])();

char (* (*x()) [])();
// 首先()优先级大于*,x是一个函数
// 函数 x 的返回值是一个指向某种类型的指针,类型是fun
char ( *fun[] )();
// [] 优先级大于 *
// fun的类型是数组,数组的每一个元素是一个函数指针
// 函数的类型
char f();

实例:
char fun()
{
    return 1;
}

char (*(*x())[2])() 
{
    char fun();
    char (*array[2])()= {&fun, &fun};
    return  &array;
}
char (*(*x[3])())[5];

char (*(  *x[3]  )())[5];
//首先[] 优先级大于 *
// x 是一个数值,数组的长度为3,数组的每个元素是一个指针
// 指针指向的类型是fun
char ( * fun () )[5];
//fun是一个函数,函数的返回值是一个指针
//指针的类型是 f,f的类型是一个char类型的数组
char f[5];

实例:
    char (*fun())[5];
    char (*(*x[3])())[5] = {&fun, &fun, &fun};

    char (*fun())[5]
    {
        char array[5];
        return &array;
    }
旧人九事 2022-09-10 08:52:58

1、x是一个函数,这个函数不接受参数,并返回指针,指针指向数组,数组的元素是函数指针,函数指针指向的函数不接受参数,并返回char

2、x是一个数组,数组包含3个函数指针,函数指针指向的函数不接受参数,并返回指针指向包含5个char元素的数组

#include <stdio.h>

typedef char (*(*baz())[])();
typedef char (*(*foo[3])())[5];
typedef char (*bar)[5];
typedef char (*(*far)[])();
typedef char (*faz)();

char boo() {};


far func1()
{
    faz array[] = {&boo, &boo};
    /*注意:这是错误做法,只是为了例子需要*/
    return &array;
}

bar func2()
{
    char array[5] = {1, 2, 3, 4, 5};
    /*注意:这是错误做法,只是为了例子需要*/
    return &array;
}


int main(int argc, const char* argv[])
{
    foo foo = {&func2, &func2, &func2};

    return 0;
}
想挽留 2022-09-10 08:52:58

能写出这种代码的人,对于后期代码维护简直就是个灾难。如果这个人走了

韵柒 2022-09-10 08:52:58

关于C语言声明问题。任何不介绍 http://cdecl.org/ 的答案都是耍流氓。
这原本其实是一个unix程序(或其他系统),被改造成了在线版。
通过这个网站,你可以检查自己的答案是否正确。

建议根据优先级来推论,不建议用替换法,因为替换的元素不同可能会导致优先级与原来的声明不同。
所以我建议参考 bbaimu 的答案。李引证的答案中有一个表达的小错误,他在表达第一题数组元素时
用了两次指针,这是不对的。正确的表述应该是 数组的每一个元素是一个函数指针

另外,建议参考书籍《C和指针》中高级指针那章,
还有《C Programming: A Modern Approach》 - K. N. King 关于声明详细介绍那章

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文