发信人: Linuxman (风继续吹), 信区: LinuxUnix
标 题: How To Read C Declarations
发信站: 云麓园 BBS 站 (Wed Mar 28 00:20:43 2007), 站内
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's a pointer to an array of pointers to functions returning
integers. ;)
This short article tells you how to read any C declaration correctly usi
ng a very simple technique. I am 99% certain that I read this in a book in the l
ate 1980s, 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 esote
rica). I do remember, however, building a simple program that would translate an
y 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 s
ee. Look left again without jumping over a parenthesis; say what you see. Jump o
ut a level of parentheses if any. Look right; say what you see. Look left; say w
hat you see. Continue in this manner until you say the variable type or return t
ype."
The degenerate case is:
int i;
Starting at i, you look right and find nothing. You look left and find the type
int, which you say. Done.
Ok, now a more complicated one:
int *a[3];
Start at a. Look right, say array of size 3. Look left and say pointer.
Look right and see nothing. Look left and say int. All together you say a 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 lo
ok right after a, you see the right parenthesis, which you cannot jump over unti
l you look left. Hence, you would say a is a pointer to an array of 3 ints.
Function pointers
----------------------
The C "forward" declaration:
extern int foo();
just says that foo is a function returning int. This follows the same pa
ttern for reading declarators as you saw in previous section. Start at foo and l
ook right. You see () so say function. You look left and see int. Say int.
Now, try this one:
extern int *foo();
Yep, you say foo is a function returning a pointer to int.
Now for the big leap. Just like we can make a pointer to an int or whate
ver, lets make a pointer to a function. In this case, we can drop the extern as
it's no longer a function forward reference, but a data variable declaration. H
ere is the basic pattern for function pointer:
int (*foo)();
You start at foo and see nothing to the right. So, to the left, you say
pointer.
Then to the right outside you see function. Then left you see int. So y
ou say foo is a pointer to a function returning int.
Combinations
--------------------
Here is an array of pointers to functions returning int, which we'll nee
d 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 def
ine.
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 t
ables ala C++ to implement polymorphism (like the original cfront C++ to C trans
lator).
int *ptr_to_int;
int *func_returning_ptr_to_int();
int (*ptr_to_func_returning_int)();
int (*array_of_ptr_to_func_returning_int[])();
int (*(*ptr_to_an_array_of_ptr_to_func_returning_int)[])();
--
我们能做的事情很多,唯一受限制的是我们的
创造力和想象力
※ 来源:·云麓园 BBS 站 bbs.csu.edu.cn·[FROM: 211.151.248.*]
--
"Where is the knowledge we have lost in information?
Where is the wisdom we have lost in knowledge?"
※ 修改:·autoca 於 04月21日17:20:43 修改本文·[FROM: 郁金香BBS站]