1) b = (TYPE_B) a
I don't think you can cast between two different struct types this way in C. If TYPE_A and TYPE_B are fundamental types it works but the result depends on the types involved.
2) b = * (TYPE_B *) &a
&a gives you a pointer to a (TYPE_A*). The pointer is then casted to a TYPE_B* so when the dereference operator * is used it will read a as if it had type TYPE_B.
The content of a is copied to b exactly how it's stored in memory, but because the two types are different they will be interpreted differently. The short value 0x0102 (258) consists of two bytes with values 1 and 2 (assuming short is 2 bytes) so when c1 and c2 is read from b it gives you value 1 and 2.
Yes, casting can lead to problems if you are not careful. I haven't used that much C to know how useful casts like these are, but remember that C has a weaker type system, no inheritance and things like that, and void* is often used as a pointer to any type, so more responsibility on the programmer to know what he's doing.
C-style casts are usually not recommended in C++, but instead we have dynamic_cast, reinterpret_cast, static_cast and const_cast for different purposes.
And to be honest, the example I posted above is probably not a good one. I think it might break the strict aliasing rules, which would make it unsafe to use.