Когда вы используете указатель '*', вы можете создать, например, массив при выделении памяти для нескольких символов. Пример char * word = malloc (10 * sizeof (char)). Ваше слово теперь имеет место для 10 символов. Когда вы хотите создать предложение, вам нужно несколько слов, чтобы вы могли создать двумерный массив. Вы можете сказать char * предложение = malloc (10 * sizeof (слово)).
В c двойной указатель часто используется для создания двумерного массива.
Когда ваша функция создаст новую игровую доску размером n * n, она вернет массив.
Например, вы вызываете char ** board = ** newArray (n);
В c вы можете создать массив типа char array [] или создать массив типа char *. Это то же самое, потому что массив в C является указателем на первый элемент массива. Но проблема в том, что вы не можете вернуть такой массив из функции, которая вам нужна для возврата указателя. Так что функция char [] () не работает, нужно сказать char * function (). И в этом случае в вашем примере вы создаете новый двумерный массив для своей платы и возвращаете указатель на первый элемент (указатель) массива, поэтому вы вызываете свою функцию char **, а не char [] [].