As helios said, C uses different name spaces for all struct-names and all other names (typedefs, build-in types etc). As C evolved to C++, Bjarne Stroustrup thought this is useless and removed it. Hence, in C++ all types share the same name space.
(Not to be confused with the C++-feature "namespace" which is ... "similar but different" :-D)
The "struct" is just to tell the C-compiler in which type table he should look. There is no other difference. Code that uses a typedef compiles to the exact same binary as one that annotates the structs with "struct type". (Ok.. it differs in the debug symbol list ;)
In C, a struct name is not automatically a type name, as it is in C++.
1 2 3 4 5 6 7 8
struct point_t{ int x; int y; };
// In C++, point_t is automatically a type name so this is valid
point_t origin;
//In C, you have to use the elaborated form
struct point_t origin;
There is only one way of defining struct (above) and its type is a structure type.
typedef is used to give the structure type a new name.
1 2 3 4 5 6 7
struct point_t{ int x; int y; };
typedefstruct point_t point_t;
// now both C and C++ can do this
point_t origin;
struct point_t pt;
For more information read up on Elaborated Type Specifier.