int x = 123456789;
See how data will be stored ,
a is pointing to address of int x.
unsigned char *c1 = (unsigned char*)a;
Now char c1 is pointing to the location of a.
Next statement is printing consequtive 4 bytes which are unsigned in nature.
So value will be:21 205 91 7 (See from above table)
char *c2 = (char*)a;
Char c2 contains address of a which is signed .Now it is printing second byte value at pointed by a.
And correspoinding value will be -51(which will fall inside signed range ).
char *c3 = (char*)a;
Char c3 contains address of a which is also signed .Now it is also printing second byte value pointed by a. But it is signed .
PS: *(c3+1) is promoted inside printf to a 32 bit integer , preserving sign. ( padding ones because, initialy *c3 was a signed char having 1 in the sign bit, and it is itself in 2's complement form). After that we read using %u specifier which simply tells how to interpret the promoted data. %u nothing to do with promotion.
So, in the last printf %u reads the promoted data 11111111111111111111111111001101 as 4294967245.