ArticleDirectory
- Function pointers
- Combinations
Terence Parr
Even experienced C programmers have difficulty reading declarations that go beyond simple arrays and pointers. For example, is the following an array of pointers or a pointer to an array?
Int * A [10];
What the heck does the following mean?
INT (* vtable) []) ();
Naturally, it'sPointer to an array of pointers to functions returning Integers.
This short article tells you how to read any c Declaration correctly using a very simple technique. I am 99% certain that I read this in a book in the late 1980 s, but I can't remember where. I doubt that I discovered this on my own (even though I 've always been delighted by computer language structure and esoterica ). I do remember, however, building a simple program that wocould translate any declaration into English.
The golden rule
The rule goes like this:
"Start at the variable name (or innermost construct if no identifier is present. look right without jumping over a right parenthesis; say what you see. look left again without jumping over a parenthesis; say what you see. jump out a level of parentheses if any. look right; say what you see. look left; say what you see. continue in this manner until you say the variable type or return type."
The degenerate case is:
Int I;
StartingI, You look right and find nothing. You look left and find the typeInt, Which you say. Done.
OK, now a more complicated one:
Int * A [3];
StartA. Look right, sayArray of size 3. Look left and sayPointer. Look right and see nothing. Look left and sayInt. All together you sayA is an array of size 3 pointers to int.
Adding parentheses is when it gets weird:
INT (* A) [3];
The parentheses change the order just like in an expression. When you look right afterA, You see the right parenthesis, which you cannot jump over until you look left. Hence, you wocould sayA is a pointer to an array of 3 ints.
Function pointers
The C "Forward" declaration:
Extern int Foo ();
Just says thatFoo is a function returning int. This follows the same pattern for reading declarators as you saw in previous section. StartFooAnd look right. you see()So sayFunction. You look left and seeInt. SayInt.
Now, try this one:
Extern int * Foo ();
Yep, you sayFoo is a function returning a pointer to int.
Now for the big leap. Just like we can make a pointer toIntOr whatever, let's make a pointer to a function. In this case, we can dropExternAs it's no longer a function forward reference, but a data variable declaration. Here is the basic pattern for function pointer:
INT (* Foo )();
You startFooAnd see nothing to the right. So, to the left, you sayPointer. Then to the right outside you seeFunction. Then left you seeInt. So you sayFoo is a pointer to a function returning int.
Combinations
Here isAn array of pointers to functions returning int, Which we'll need for vtables below:
INT (* object_vtable []) ();
You need one last, incredibly bizarre declaration, for the lab:
INT (* vtable) []) ();
This is the pointer to the vtable you will need in each "object" You define.
This pointer to a vtable is set to the address of a vtable; for example,& Truck_vtable.
Summary
The following examples summarize the cases needed for building virtual tables Ala C ++ to implement polymorphism (like the originalCfrontC ++ to C translator ).
Int * ptr_to_int; int * func_returning_ptr_to_int (); int (* ptr_to_func_returning_int) (); int (* minute []) (); int (* minute) []) ();