Feb
25
How To Read C Declarations
这篇看起来忒有意思,回头有空了我翻译一下。
How To Read C Declarations
zz from http://blog.chinaunix.net/u1/36290/showart_443799.html
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?
What the heck does the following mean?
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 using a very simple technique. I am 99% certain that I read this in a book in the late 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 esoterica). I do remember, however, building a simple program that would translate any declaration into English.
The golden rule
The rule goes like this:
The degenerate case is:
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:
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:
The parentheses change the order just like in an expression. When you look right after a, you see the right parenthesis, which you cannot jump over until you look left. Hence, you would say a is a pointer to an array of 3 ints.
Function pointers
The C "forward" declaration:
just says that foo is a function returning int. This follows the same pattern for reading declarators as you saw in previous section. Start at foo and look right. You see () so say function. You look left and see int. Say int.
Now, try this one:
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 whatever, let's 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. Here is the basic pattern for function pointer:
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 you say foo is a pointer to a function returning int.
Combinations
Here is an array of pointers to functions returning int, which we'll need for vtables below:
You need one last, incredibly bizarre declaration, for the lab:
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 original cfront C++ to C translator).
转载请注明出自 ,如是转载文则注明原出处,谢谢:)
RSS订阅地址: https://www.felix021.com/blog/feed.php 。
How To Read C Declarations
zz from http://blog.chinaunix.net/u1/36290/showart_443799.html
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 using a very simple technique. I am 99% certain that I read this in a book in the late 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 esoterica). I do remember, however, building a simple program that would 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;
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 look right after a, you see the right parenthesis, which you cannot jump over until 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 pattern for reading declarators as you saw in previous section. Start at foo and look 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 whatever, let's 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. Here 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 you say foo is a pointer to a function returning int.
Combinations
Here is an 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 original cfront C++ to C translator).
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)[])();
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)[])();
欢迎扫码关注:
转载请注明出自 ,如是转载文则注明原出处,谢谢:)
RSS订阅地址: https://www.felix021.com/blog/feed.php 。
nanduo
2009-3-22 23:22
可以看《c陷阱与缺陷》, 讲的很清楚
felix021 回复于 2009-3-23 09:57
唔,谢谢。这篇已经很清楚了:)
分页: 1/1 1