Двукратный указатель - это переменная, которая содержит адрес указателя, то есть это указатель на указатель.
Двукратные указатели часто используются в системных программах. Трехкратные указатели встречаются редко. Язык Си допускает так же использование многократных указателей (например, ****p). Однако, лучше избегать этого.
Объявление двукратного указателя:
тип **идентификатор;
Пример 1

/*пример сканера для идентификации команд */
#include <stdio.h>
#include <string.h>
int is_keyword(char *);
char *keyword[] = {
                   "append",
                   "find",
                   "list",
                   "remove",
                   "replace",
                   "substitute",
                   (char *)NULL
                   };
/*возвращает индекс команды, иначе -1*/
int is_keyword(char *)
  {
  char **p;
  for (p=keyword; *p != NULL; p++)
     if(strcmp(str, *p) == 0)
        return p-keyword;
  return -1;
  }
Массив keyword - это массив указателей на символ, который инициализируется адресами строковых констант. Такие указатели обычно не изменяются во время выполнения программы. Двукратный указатель p используется для перебора элементов массива.
p содержит адрес одного из элементов массива keyword, *p - это адрес строки, записанный в этом элементе массива, а **p (в примере не используется) указывает на первый символ в этой строке.