Dai un pesce a un uomo e lo nutrirai per un giorno; insegnagli a pescare e lo nutrirai per tutta la vita.
RIGHT-LEFT RULE: "
vai a destra quando puoi, vai a sinistra quando devi".
Tale regola ti permette di interpretare qualsiasi dichiarazione in C/C++, anche quelle più complicate. Ovviamente puoi utilizzarla anche nel caso contrario, ossia quando devi essere tu a scrivere una precisa dichiarazione.
SPIEGAZIONE: si parte dall'identificatore e si segue la regola facendo attenzione alla precedenza dettata dalle parentesi tonde.
Nel tuo caso:
int const *
a[8] a è...
int const *
a[8] a è un array di 8...
int const
*a[8] a è un array di 8 puntatori a...
int
const *a[8] a è un array di 8 puntatori a costante di tipo...
int const *a[8] a è un array di 8 puntatori a costante di tipo int
Bisogna inoltre specificare che un eventuale const riferito al tipo più esterno (ossia il primo tipo che incontriamo all'interno della dichiarazione) può essere messo anche all'inizio della dichiarazione, cioè alla sinistra del tipo più esterno. In pratica questo significa che
int const *a[8];
coincide con
const int *a[8];
@saraciao
Detto questo, si deduce che sia la tua scrittura che quella di @oregon sono sbagliate, in quanto non rappresentano un "un array di 8 puntatori costanti a interi", ma un array di 8 puntatori a costanti intere.
Come detto da @Unqualunque, la scrittura corretta è:
int * const a[8] = {...};
Prova ad utilizzare la RIGHT-LEFT RULE per rendertene conto.
Inoltre ti faccio notare che quelle parentesi graffe non sono un optional!