Указатель на указатель.
Используется…
1. Для многомерных массивов (в Си нечасто — ведь есть настоящие многомерные массивы; обычно в структурах посложнее, чем тупой массив M×N). Вот у меня есть самодельный (неполный) аналог std::deque (динамический массив, состоящий из кусочков и никогда ничего не перемещающий). Там внутри std::vector<T*>, который служит массивом массивов. А у вектора внутри — T**.
2. Для массивов (1-е измерение) строк (2-е измерение).
3. Для передачи указателя по указателю (см. описание функции strtod).
4. (Крайне редко) И просто как указатель на указатель
Как инициализировать?
1.
char row0[] = { 'A', 'B' };
char row1[] = { 'C', 'D' };
char* arr1[] = { row0, row1 };
char** data1 = arr;
2.
char* arr2[] = { "AB", "CD" };
char** data2 = arr2;
3.
char* errptr;
int r = strtod("10", &errptr);
return (*errptr != '\0') ? ERROR : r;
4.
char* data = "Data";
char** pData = &data;