В чем различие void func(char * var) от void func(char **var)?
Это плохо. Указатели - основа С, без понимания того, как работают указатели, будет ооочень трудно.
char *var - указатель на переменную типа char. Сама var содержит адрес, шестнадцатеричное число, размер его зависит от реализации, от ОС, от платформы etc. Этот адрес указывает на область памяти длиной 1 байт (потому что char *), соответственно в эту область можно поместить 1 байт. Если поместить туда скажем переменную типа short int (два байта), то можно получить опять же в зависимости от того, как получали под нее память либо затирание соседней переменной (что не всегда плохо и очень часто используется для обнуления областей), либо SIGSEGV, то есть нарушение защиты памяти, запись в область памяти не выделенную программе.
char ** var - указатель на указатель на переменную типа char. Сама var, как и раньше содержит адрес, но теперь этот адрес указывает на область памяти размером с указатель (он фиксированный в пределах реализации) и по этому адресу записан адрес области, в которую можно поместить 1 байт (со всеми вытекающими последствиями).
Зачем такие извращения? Ну, например для упрощения вызова функции - передавать один параметр или же 4-5. Обработка списков, деревьев и всего, что строится на их основе. Данная конструкция очень распространена, рекомендую проработать пару демок в отладчике - с дотошным разбором, где что находится, как откуда и куда извлекается...
char* var - одномерный указатель типа char 
Его можно использовать так:
1) char t='1';
char* var=&t;
*var = '2';
2)
Массив char var[10]; сам по себе является указателем, а потому его не надо разыменовывать и проч.
3)
char** var-двумерный указатель
Использовать можно так:char** var= new char*[10]; 
for(int i=0;i<10;i++){
    var[i] = new char[10]; 
}