On Friday, Apr 11th 2008 at 17:19 -0000, quoth Bill Davidsen: =>Matthew Saltzman wrote: =>> On Tue, 2008-04-08 at 15:27 -0400, Steven W. Orr wrote: =>> > On Tuesday, Apr 8th 2008 at 13:39 -0000, quoth Les: =>> > =>> > =>On Tue, 2008-04-08 at 09:39 -0600, Robin Laing wrote: =>> > =>> max bianco wrote: =>> > =>> > I want to learn C and I know there are quite a few programmers on =>> > this =>> > =>> > list. I am looking for a couple of good books on learning C. I am =>> > not =>> > =>> > exactly a beginner but I am no expert and i would like to start =>> > going =>> > =>> > over everything from scratch. =>> > One thing I've noticed over the years is that the majority of C coders out =>> > there, no matter how good they are, never really master the ability to =>> > composed and decompose complex declarations and references. I don't say =>> > this in a perjorative fashion, but I see it a lot and it's important to be =>> > able to distinguish between an array of pointers to integers and a pointer =>> > to an array of integers, i.e., =>> > =>> > int *foo[10]; =>> > int (*foo)[10]; =>> > =>> > Going through K&R is standard, but this is a basic complaint I've had for =>> > a long time. =>> =>> This comment reminded me of the fabulously useful little utility cdecl =>> (and its cousin c++decl) which translates between the English =>> description of a declaration in C (resp. C++) and the actual C (resp. =>> C++) code itself. cdecl tells you what it is but it doesn't tell you how to do it. Since I have a few and I'm feeling inspired, here are the quick and simple rules for declarations and referencing.: * There are three operators. *, {} and () * The () is the function operator and is not to be confused with the parens used to alter precedence. * The * is pronounced "pointer which returns a BLANK". * The [] is pronounced "an array of BLANKS". * The () is pronounced "a function which returns a BLANK" * An array can not hold functions. It can however contain pointers to functions. * A function can not return an array or a function. It can however return a pointer to an array or a function. * The precedence of function and array operators are equal and associate from left to right. * The precedence of pointer is lower than the precedence of functions or arrays. High Precedence () [] left -> right Lower Precedence * left <- right That's it. So something like typedef void (*sighandler_t) (int); sighandler_t signal(int signum, sighandler_t handler); now becomes easy peasy. "sighandler_t is a type which is a pointer to a function which takes an int as an arg and returns void. Signal is a function which takes an int and a sighandler_t as args and returns a sighandler_t. This is (more or less) equivalent: void (*signal( int signum, void hdlr(int))(int) Quiz for next Friday. What are these and what's the difference between them: int (*(**p)[])(int) and int *(*(**p)[])(int) -- Time flies like the wind. Fruit flies like a banana. Stranger things have .0. happened but none stranger than this. Does your driver's license say Organ ..0 Donor?Black holes are where God divided by zero. Listen to me! We are all- 000 individuals! What if this weren't a hypothetical question? steveo at syslang.net