I think if all type-information were kept together, it might read simpler:
char*[X] arr;
You read strictly left to right: char pointer array of size X called arr. Basically, it takes a simple type (char in this case) and for each thing to the right, wraps it in something. You could read it as: given a char, we have a pointer to it, and an array of size X of these pointers.It would be interesting if the use did "mirror" declaration:
arr[5]*
That is, take element 5 of arr and derefence it.Just some random thoughts...