struct and typedef are two very different things.
The struct keyword is used to define, or to refer to, a structure type. For example, this:
struct foo {
int n;
};
creates a new type called struct foo. The name foo is a tag; it's meaningful only when it's immediately preceded by the struct keyword, because tags and other identifiers are in distinct name spaces. (This is similar to, but much more restricted than, the C++ concept of namespaces.)
A typedef, in spite of the name, does not define a new type; it merely creates a new name for an existing type. For example, given:
typedef int my_int;
my_int is a new name for int; my_int and int are exactly the same type. Similarly, given the struct definition above, you can write:
typedef struct foo foo;
The type already has a name, struct foo. The typedef declaration gives the same type a new name, foo.
The syntax allows you to combine a struct and typedef into a single declaration:
typedef struct bar {
int n;
} bar;
This is a common idiom. Now you can refer to this structure type either as struct bar or just as bar.
Note that the typedef name doesn't become visible until the end of the declaration. If the structure contains a pointer to itself, you have use the struct version to refer to it:
typedef struct node {
int data;
struct node *next; /* can't use just "node *next" here */
} node;
Some programmers will use distinct identifiers for the struct tag and for the typedef name. In my opinion, there's no good reason for that; using the same name is perfectly legal and makes it clearer that they're the same type. If you must use different identifiers, at least use a consistent convention:
typedef struct node_s {
/* ... */
} node;
(Personally, I prefer to omit the typedef and refer to the type as struct bar. The typedef save a little typing, but it hides the fact that it's a structure type. If you want the type to be opaque, this can be a good thing. If client code is going to be referring to the member n by name, then it's not opaque; it's visibly a structure, and in my opinion it makes sense to refer to it as a structure. But plenty of smart programmers disagree with me on this point. Be prepared to read and understand code written either way.)
(C++ has different rules. Given a declaration of struct blah, you can refer to the type as just blah, even without a typedef. Using a typedef might make your C code a little more C++-like -- if you think that's a good thing.)