The relevant part of the code snippet is:
char T[2];
scanf("%s", &T);
&T is a pointer to the array of two characters (char (*)[2]). This is not the type that scanf needs for a %s specifier: it needs a pointer to a character (char *). So the behavior of the program is undefined.
The correct way to write this program, as you know, is
char T[2];
scanf("%s", T);
Since T is an array, when it is used in most contexts, it “decays” to a pointer to the first character: T is equivalent to &(T[0]) which has the type char *. This decay does not happen when you take the address of the array (&T) or its size (sizeof(T)).
In practice, almost all platforms use the same representation for all pointers to the same address. So the compiler generates exactly the same code for T and &T. There are some rare platforms that may generate different code (I've heard of them but I couldn't name one). Some platforms use different encodings for “byte pointers” and “word pointers”, because their processor natively addresses words, not bytes. On such platforms, an int * and a char * that point to the same address have different encodings. A cast between those types converts the value, but misuse in something like a variable argument list would result in the wrong address. I would expect such platforms to use byte addresses for a char array, however. There are also rare platforms where a pointer encodes not only the address of the data, but also some type or size information. However, on such platforms, the type and size information would have to be equivalent: it's a block of 2 bytes, starting at the address of T, and addressable byte by byte. So this particular mistake is unlikely to have any practical impact.
Note that it would be completely different if you had a pointer instead of an array in the first place:
char *T; // known to point to an array of two characters
scanf("%s", &T); // bad
Here &T is a pointer to the location in memory that contains the address of the character array. So scanf would write the characters that it reads at the location where the pointer T is stored in memory, not at the location that T points to. Most compilers analyze the format string of functions like printf and scanf and so would emit an error message.
Note that char T[2] only has room for two characters, and this includes the null byte at the end of the string. So scanf("%s", T) only has room to read a single character. If the input contains more than one non-whitespace character at this point, the program will overflow the buffer. To read a single character and make it a one-character string, use
char T[2];
scanf("%c", T);
T[1] = 0;
Unlike scanf("%s", T), this reads any character, even whitespace. To read a string with a length limit, add a limit to the %s specification. You should never use an unlimited %s in scanf since this will read as much input as is available, regardless of how much room there is to store this input in memory.
char T[2];
scanf("%1s", T); // one less than the array size