Lo que estamos haciendo mediante los punteros es algo que técnicamente se conoce como “direccionamiento indirecto”: cuando hacemos int *n, generalmente no nos va a interesar el valor de n, sino que n es una dirección de memoria a la que debemos ir a mirar el valor que buscamos.
Pues bien, podemos hacer que ese direccionamiento sea todavía menos directo que en el caso normal: algo como int **n se referiría a que n es una dirección de memoria, en la que a su vez se encuentra como dato otra dirección de memoria, y dentro de esta segunda dirección de memoria es donde se encuentra el dato. Es decir, n sería un “puntero a puntero a entero”.
Esta no es una situación habitual, así que no profundizaremos más en ella.
Aun así, lo que sí se debe recordar es que char **datos es algo muy parecido a char datos[][], por lo que alguna vez lo veremos indicado como parámetros de una función de una forma o de la otra.