It seems that the used compiler placed the local variables x, y, z in memory in the reverse order relative to their declarations. That is the variable z in memory is followed by the variable y that in turn is followed by the variable x.
Now consider the first call of scanf
scanf("%2c",&x);
According to the description of the function fscanf (that is valid for the function scanf) in the C Standard the following occurs
c Matches a sequence of characters of exactly the number specified by the field width (1 if no field width is present in the directive).
where c is the conversion specifier used in your call of scanf.
That is the function tries to read exactly 2 characters from the input buffer to the memory starting with the address specified by the expression &x.
Thus two characters are read from the input buffer. The first character 'A' is written in the variable x and the second character 'B' overwrites the memory used by the program after the variable x that results in undefined behavior.
In the next step
scanf("%3c",&y);
next three characters are read from the input buffer. The first character 'C' is stored in the memory of the variable y, the next character 'D' is stored in the memory occupied by the variable x and the third character again overwrites the memory after the variable x.
In the third and last step
scanf("%4c",&z);
four characters are read from the input buffer. The variable z gets the character 'F', the variable y that follows in memory the variable z gets the character 'G' and the variable x that follows the variable y gets the character 'H'. The fourth character of the input buffer that represents the new line character '\n' that corresponds to the pressed key Enter again overwrites memory.
The program could have a valid behavior if you declared a character array that can accommodate four characters from the input buffer.
For example
enum { N = 4 };
char s[N];
scanf("%2c", s);
scanf("%3c", s);
scanf("%4c", s);
printf( "%.*s", N, s );
char x[3]; scanf("%2c", &x)does not assign a null terminator.