繁体   English   中英

这些指针的含义,pointer-to-pointer,function指针和数组指针

[英]meaning of these pointers, pointer-to-pointer, function pointer and array pointer

我是一名大学生,我们的老师让我们说出这些指针的含义,但我只能弄清楚其中的一些:

1. int *p1;
2. int *p2[10];
3. int (*p3)[10];
4. int (*p4)();
5. int **p5();
6. int (**p6)[10];
7. int (**p7)();
8. int *(*p8)();
9. int (*p9[10])();
10. int **p10[10];

这是我到目前为止所知道的:

  • p1 是一个指向 int 的指针
  • p2 是一个包含 10 个 int 指针的数组
  • p3 是指向具有 10 个元素的静态数组的指针
  • p4 是一个 function 指针
  • p5 根本不是指针,而是返回 int 的 function 的原型**
  • p6 是一个包含 10 个指针的数组
  • p7 是指向 function 指针的指针

你们能帮帮我吗? 因为我们的老师告诉我们这些将在考试中

cdecl.org可用于破译混乱的声明,如您的示例:

int (*p9[10])(); => 将 p9 声明为指向 function 返回 int 的指针的数组 10

如果做不到这一点,您可以使用顺时针/螺旋规则手动打磨它们。

所有 7 个指针都正确确定,但您应该指定参数类型和返回类型。

例如:

  1. int **p5(); - function 没有 arguments,返回指向int的指针的指针。

  1. int *(*p8)(); - 指向没有 arguments 的 function 的指针,返回指向int的指针。
  2. int (*p9[10])(); - 指向 function 的 10 个指针数组,没有 arguments,返回int
  3. int **p10[10]; - 10 个指向int指针的数组。

如果我是编译器,我可以提示空参数列表,就像 fe clang 所做的那样:

警告:这个 function 声明不是原型 [-Wstrict-prototypes]

在实践中使用这些构造时,使用(void)而不是()


请注意,如果您正在参加考试,请考虑大卫安德森的顺时针/螺旋规则,如图所示

1>指向integer的指针

int *p1;
```````````````````````````````````````
2>array of 10 pointer which point to integer
`````````````````````````````````
int *p2[10];
`````````````````````````````````
3> pointer to an array of 10 integers
```````````````````````
int (*p3)[10]
``````````````````````````````````````
4> pointer to function that takes void argument and return integer
`````````````
int (*p4)();
```````````````
5>> is a prototype(deceleration)  of a function which called p5 and returns int** 
````````````
int **p5();
``````````
6>> is an array of 10 pointer-to-pointer which point to integer values
`````````
 int (**p6)[10]
````````
7>>is pointer to pointer to function that takes void argument and return int
``````````````
int (**p7)();
````````````````
8>>pointer to function that takes void argument and return address or pointer
`````````````````
int *(*p8)();
`````````````
9>>array of 10 pointers to functions that take void argument and return an integer
``````````````````
 int (*p9[10])();
```````````````
10>> it indicate to the first element in an array of 10 pointers which point to integer values 
```````````
int **p10[10];
```````````

有一些技巧可以阅读和理解复杂的声明。 有一种称为“顺时针螺旋规则”的技巧,您从标识符开始,然后从右边的任何内容开始向外螺旋。 例如,给定声明

int *(*a[N])(void);

我们将其追踪为:

                 +-----------------------+
                 | +-----------+         |
                 | | +-------+ |         |
                 | | | +-+   | |         |
                 | | | | |   | |         |
             int * ( * a [N] ) ( void )  |
             ^   | | |   |   | |         |
             |   | | +---+   | |         |
             |   | +---------+ |         |
             |   +-------------+         |
             +---------------------------+

或者

                   a                -- a
                   a[N]             -- is an N-element array
                  *a[N]             -- of pointers
                 (*a[N])(    )      -- to functions taking
                 (*a[N])(void)      --   no parameters
                *(*a[N])(void)      -- returning pointer to
            int *(*a[N])(void);     -- int

请记住,后缀下标[]和 function call ()运算符的优先级高于一元解引用*运算符,因此*a[i]*f()之类的表达式被解析为*(a[i])*(f()) - 我们取消引用a[i]f()的结果。 如果a指向一个数组,那么我们需要对*a结果进行索引,因此我们需要使用括号将*a - (*a)[i]显式分组。 同样,如果f指向一个 function,那么我们需要调用*f的结果,所以我们必须写(*f)()

这是一个具有多个间接的示例:

int **foo(void);

分解为

      foo             -- foo
      foo(    )       -- is a function taking
      foo(void)       --   no parameters
     *foo(void)       -- returning a pointer
    **foo(void)       -- to a pointer
int **foo(void);      -- to int

您将递归地将这些规则应用于任何 function 参数。 这是来自标准库的signal function 的声明:

void (*signal(int sig, void (*func)(int)))(int);

读作

       signal                                    -- signal
       signal(                          )        -- is a function taking
       signal(    sig                   )        --   parameter sig
       signal(int sig                   )        --     is an int
       signal(int sig,        func      )        --   parameter func
       signal(int sig,       *func      )        --     is a pointer
       signal(int sig,      (*func)(   ))        --     to a function taking
       signal(int sig,      (*func)(int))        --       parameter unnamed is an int
       signal(int sig, void (*func)(int))        --     returning void
     (*signal(int sig, void (*func)(int)))       -- returning a pointer
     (*signal(int sig, void (*func)(int)))(   )  -- to a function taking
     (*signal(int sig, void (*func)(int)))(int)  --   unnamed parameter is an int
void (*signal(int sig, void (*func)(int)))(int); -- returning void

您还可以使用一些替代技巧。 如果您需要弄清楚如何声明一个指向函数的指针数组,该数组返回指向其他函数的指针,返回指向指向int的指针的 arrays 的指针,请从T的数组开始:

T a[N];   // a is an array of T

这将是一个指向某物的指针数组,因此将T替换为指针类型P

P *a[N];  // a is an array of pointer to P

每个a[i]将是一个指向 function 的指针,因此将P替换为 function 类型F

F (*a[N])( );

这些函数中的每一个都返回一个指针,因此将F替换为另一个指针类型P

P *(*a[N])( );

这些指针中的每一个都指向另一个 function,所以

F (*(*a[N])( ))( );

这些函数返回指针,因此我们将F替换为另一个指针类型P

P *(*(*a[N])( ))( );

P替换为数组类型A

A (*(*(*a[N])( ))( ))[M];

从这里我们可以直接跳到最后:

int *(*(*(*a[N])( ))( ))[M];

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM