You are correct that langStrings contains pointers to pointers to an array of characters. Therefore, each langString[i] points to a pointer. This pointer points to an array. This array contains the name of the language.
As others have noted, this looks a bit awkward. I will clarify:
char eLangAr[20] = "English"; - an array of 20 characters, and the name " English " is copied to it. I do not expect the eLangAr variable to ever contain anything other than this language name, so there is no need to use an array; the constant will be sufficient.
char **langStrings [3]= ... Itβs enough to have only one indirectness (one *), since there is no need to ever have a pointer to anything else (randomly shuffle languages?).
in conclusion, it is sufficient to have the following:
const char *langStrings [3]= { "English", "French", "German" };
(Note const because strings are now read-only constants / literals.)
The fact that this code can be useful is when these language names must be written differently in different languages. So "English", "French", "German" became "Engels", "France", "Dwits." However, then there is still one level of indirection too much, and it will be enough:
char *langStrings [3]= { aLangArr, fLangAr, gLangAr };
source share