why would I want
int *iAbc = 123;
instead of
int iAbc = 123;
The first one is a pointer that you set to the RAM address 123. The pointer is for variable type int.
The second one makes space for an int in RAM that the name iABC in your code locates and sets that int to the value 123.
They are not the same at all. You would use one instead of the other to do something different.
why would I want
char *language[][4]={{"A","B","C","D"},{"1","2","3","4"}};
instead of
char language[][4]={{"A","B","C","D"},{"1","2","3","4"}};
?
The second one won't work. If you experimented with the code it would tell you and you wouldn't understand.
The second line should be
char language[][4][2]={{"A","B","C","D"},{"1","2","3","4"}};
The [2] is the number of characters allowed per string (double quotes makes string) which can be > 2.
Why 2 for 1 letter? Because all C strings must end with a zero byte to mark the end.
C string "A" is 2 bytes. One byte for 'A' (ASCII code 65, the byte value is 65) and one byte for the 0.
The [4] is for sets of 4 strings.
The [] is for however many sets there are but you can put a number there.
Between your lack of understanding variables and strings and pointers, you are confused.
This is a good time to not just read but work out simple sketches to find out every last little part that you are not completely sure of. Whatever you suspect, try. Even a fail provides some information.