char (*p)[12] = ...
С предыдущим у вас есть НЕ , определенный массив из 12 элементов, каждый из которых является указателем на символ НО указатель в массив с 12 символами.
Как объяснено в следующих строках:
int *a[3];
Начните с. Посмотрите направо, скажите массив размером 3. Посмотрите налево и скажите указатель. Посмотри правильно и ничего не увидишь. Посмотрите налево и скажите int. Все вместе вы говорите, что это массив указателей размера 3 на int.
Добавление скобок - это когда странно:
int (*a)[3];
Скобки меняют порядок, как в выражении. Когда вы смотрите справа после a, вы видите правую скобку, которую вы не можете перепрыгнуть, пока не посмотрите налево. Следовательно, вы бы сказали, что a является указателем на массив из 3-х целых.
Проверьте эти ссылки для лучшего объяснения:
Тем не менее, если вы хотите передать массив в функцию, вы можете либо скопировать его, либо, поскольку это массив, передать указатель на первый элемент (вы можете просто сделать это, используя имя массива):
myMethod( p ) <- how you call the function
Лично я предпочел бы последний случай, поскольку вы передаете функции простой указатель, а не массив в виде копии всех ее элементов