Joona said:
dreamcatcher said:
I always have this idea that typedef a data type especially a structure
is very convenient in coding, but my teacher insisted that I should use
the full struct declaration and no further explanations, so I wonder is
there any good using typedef ? and I also know that when a data type
being typedefed become an abstract data type, so what exactly is an
abstract data type, is it any good ?
Typedeffing structs is a bad idea, but there *are* good uses for
typedef. Particularly with function pointers. [...]
Using or avoiding typedef with struct and union types
seems to be a matter of taste. I haven't seen any solid
technical reason to favor one practice over the other, so
it comes down to "de gustibus." (Personally, I'm in the
use-the-typedef camp -- but I have no particular quarrel
with people who feel otherwise.)
In addition to Joona's example of using typedef to
clarify gnarly function declarations, another place I find
typedef useful is in accommodating the uncertainties about
the sizes of C's types. For example, if I need an integer
type capable of representing values up to one million, it
is unsafe to use `int' because it might only go as high as
32767. `long' will go to at least 2147483647 and will
therefore suffice, but on some machines `long' will be
serious overkill and a waste of space. If I need to store a
large quantity of these numbers, I'd like to use the smallest
possible type.
Preprocessor tests coupled with typedef provide a way to
handle this portably and with minimal ugliness:
#include <limits.h>
#if CHAR_MIN <= -1000000 && 1000000 <= CHAR_MAX
typedef char Million;
#elif SHRT_MIN <= -1000000 && 1000000 <= SHRT_MAX
typedef short Million;
#elif INT_MIN <= -1000000 && 1000000 <= INT_MAX
typedef int Million;
#else
typedef long Million; /* known to suffice */
#endif
Thereafter, I can just write `Million' whenever I mean "a
sufficiently but not unnecessarily wide integer:"
Million *ptr = malloc(1234567 * sizeof *ptr);
Million smallest, largest;
Million func(void);
... and so on; the result of all the grungy decision-making
has been conveniently packaged into the single word `Million'.
One shortcoming, though, is illustrated by this code:
Million value = 42;
printf ("value = %d\n", value); /* WRONG */
The problem is that if `Million' actually turns out to be an
alias for `long', the "%d" format specifier ought to be "%ld"
instead. One way to deal with this is to define a FMT_MILLION
macro as either "d" or "ld" in the testing above; you could
then write
printf ("value = %" FMT_MILLION "\n", value);
This works, but is clumsy to write and makes a mess for some
kinds of tools that assist with translating message strings
to multiple languages. I prefer the simpler
printf ("value = %ld\n", (long)value);
... even though it may cost a little more at run time.
In short: typedef is convenient when you'd like to hide
the details of some type decisions from the eventual user
(possibly yourself).