问题
I'm a university student, our teacher told us to tell the meaning of these pointers, but I only manage to figure out some of them:
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];
This is what I've figured out so far:
- p1 is a pointer to an int
- p2 is an array of 10 int pointer
- p3 is a pointer that point to a static-array with 10 elements
- p4 is a function pointer
- p5 is not a pointer at all but a prototype of a function that returns int**
- p6 is an array of 10 pointer-to-pointer
- p7 is a pointer to a function pointer
Can you guys please help me? Because our teacher told us these will be on the exam
回答1:
cdecl.org can be used to decipher messy declarations like your examples:
int (*p9[10])();
=> declare p9 as array 10 of pointer to function returning int
Failing that, you can use Clockwise/Spiral Rule to grind through them manually.
回答2:
All 7 pointers are correctly determined, but you should specify the parameter type and the return type with.
For example:
int **p5();
- function with no arguments, returning a pointer to pointer toint
.
int *(*p8)();
- pointer to function with no arguments, returning a pointer toint
.int (*p9[10])();
- array of 10 pointer to function with no arguments, returningint
.int **p10[10];
- array of 10 pointer to pointer toint
.
If I were a compiler I could hint the empty parameter list, like f.e. clang does:
"warning: this function declaration is not a prototype [-Wstrict-prototypes]"
Use (void)
instead of ()
, when using these constructs in practice.
Note if you are on an exam, think of David Anderson`s Clockwise/Spiral Rule, as illustrated here.
回答3:
1>pointer to 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];
```````````
回答4:
There are some techniques to reading and understanding complex declarations. There's a trick known as the "clockwise spiral rule", where you start with the identifier and spiral outward starting with whatever's immediately to the right. For example, given the declaration
int *(*a[N])(void);
we'd trace it as:
+-----------------------+
| +-----------+ |
| | +-------+ | |
| | | +-+ | | |
| | | | | | | |
int * ( * a [N] ) ( void ) |
^ | | | | | | |
| | | +---+ | | |
| | +---------+ | |
| +-------------+ |
+---------------------------+
or
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
Remember that the postfix subscript []
and function call ()
operators have higher precedence than the unary dereference *
operator, so expressions like *a[i]
and *f()
are parsed as *(a[i])
and *(f())
- we're dereferencing the results of a[i]
and f()
. If a
points to an array, then we need to index into the result of *a
, so we need to use parentheses to explicitly group *
with a
- (*a)[i]
. Similarly, if f
points to a function, then we need to call the result of *f
, so we have to write (*f)()
.
Here's an example with multiple indirection:
int **foo(void);
which breaks down as
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
You'd recursively apply these rules to any function parameters. Here's the declaration of the signal
function from the standard library:
void (*signal(int sig, void (*func)(int)))(int);
which reads as
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
There are also some substitution tricks you can play with. If you need to figure out how to declare an array of pointers to functions returning pointers to other functions returning pointers to arrays of pointers to int
, start with an array of T
:
T a[N]; // a is an array of T
This is going to be an array of pointers to something, so replace T
with a pointer type P
:
P *a[N]; // a is an array of pointer to P
Each a[i]
is going to be a pointer to a function, so replace P
with the function type F
:
F (*a[N])( );
Each of these functions returns a pointer, so replace F
with another pointer type P
:
P *(*a[N])( );
Each of these pointers points to another function, so
F (*(*a[N])( ))( );
Those functions return pointers, so we replace F
with another pointer type P
:
P *(*(*a[N])( ))( );
Replace P
with an array type A
:
A (*(*(*a[N])( ))( ))[M];
And from here we can skip straight to the end:
int *(*(*(*a[N])( ))( ))[M];
来源:https://stackoverflow.com/questions/62265769/meaning-of-these-pointers-pointer-to-pointer-function-pointer-and-array-pointe