这些指针的含义,指针指针,函数指针和数组指针
Posted
技术标签:
【中文标题】这些指针的含义,指针指针,函数指针和数组指针【英文标题】:meaning of these pointers, pointer-to-pointer, function pointer and array pointer 【发布时间】:2020-06-08 15:36:34 【问题描述】:我是一名大学生,我们的老师让我们说出这些指针的含义,但我只能弄清楚其中的一些:
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 是一个函数指针 p5 根本不是指针,而是返回 int** 的函数原型 p6 是一个包含 10 个指针的数组 p7 是指向函数指针的指针你们能帮帮我吗?因为我们的老师告诉我们这些将在考试中进行
【问题讨论】:
如果你想具体一点,例如在 p4 中:p4 是一个指向函数的指针,不带参数并返回int
。那么p8应该更容易。唯一的区别是返回值。
这是你的作业吗?
不是真正的作业,我老师说有的要考试
【参考方案1】:
cdecl.org 可用于破译您的示例中的杂乱声明:
int (*p9[10])();
=> 将 p9 声明为数组 10,指向返回 int 的函数的指针
如果做不到这一点,您可以使用Clockwise/Spiral Rule 手动打磨它们。
【讨论】:
【参考方案2】:所有7个指针都正确确定,但你应该指定参数类型和返回类型。
例如:
int **p5();
- 不带参数的函数,返回指向 int
的指针。
int *(*p8)();
- 指向不带参数的函数的指针,返回指向 int
的指针。
int (*p9[10])();
- 包含 10 个指针的数组,指向不带参数的函数,返回 int
。
int **p10[10];
- 包含 10 个指针的数组,指向指向 int
的指针。
如果我是编译器,我可以提示空参数列表,例如 f.e.铿锵声:
"警告:此函数声明不是原型 [-Wstrict-prototypes]"
在实践中使用这些构造时,请使用 (void)
而不是 ()
。
请注意,如果您正在参加考试,请想想 David Anderson 的 Clockwise/Spiral Rule,如图所示 here。
【讨论】:
【参考方案3】:1>指向整数的指针
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];
```````````
【讨论】:
【参考方案4】:有一些技巧可以阅读和理解复杂的声明。有一个称为“顺时针螺旋规则”的技巧,您从标识符开始,然后从右边的任何内容开始向外螺旋。例如,给定声明
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
请记住,后缀下标[]
和函数调用()
运算符的优先级高于一元解引用运算符*
,因此*a[i]
和*f()
等表达式被解析为*(a[i])
和*(f())
- 我们取消引用 a[i]
和 f()
的结果。如果a
指向一个数组,那么我们需要索引到*a
的result,所以我们需要使用括号将*
与a
-(*a)[i]
显式分组。同样,如果f
指向一个函数,那么我们需要调用*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
您可以递归地将这些规则应用于任何函数参数。下面是标准库中signal
函数的声明:
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
的指针数组的指针,从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]
都将是一个指向函数的指针,因此请将P
替换为函数类型F
:
F (*a[N])( );
这些函数中的每一个都返回一个指针,因此请将F
替换为另一种指针类型P
:
P *(*a[N])( );
这些指针中的每一个都指向另一个函数,所以
F (*(*a[N])( ))( );
那些函数返回指针,所以我们将F
替换为另一种指针类型P
:
P *(*(*a[N])( ))( );
将P
替换为数组类型A
:
A (*(*(*a[N])( ))( ))[M];
从这里我们可以直接跳到最后:
int *(*(*(*a[N])( ))( ))[M];
【讨论】:
以上是关于这些指针的含义,指针指针,函数指针和数组指针的主要内容,如果未能解决你的问题,请参考以下文章