Массив указателей — структура, где каждый элемент представляет собой указатель, обычно на один и тот же тип. Используется, например, для хранения списка строк (char *arr[];).
Указатель на массив — переменная, хранящая адрес начала всего массива (например, int (*ptr)[10]; указывает на массив из 10 элементов int).
Примеры:
// Массив указателей на char (массив строк) char *days[] = {"Sun", "Mon", "Tue"}; // Указатель на массив из 10 целых чисел int arr[10]; int (*p)[10] = &arr; // Обращение: printf("%s", days[1]); // "Mon" printf("%d", (*p)[0]); // arr[0]
"Чем отличается
char *arr[3];отchar (*arr)[3];и как правильно обращаться к строкам в каждом случае?"
Многие считают, что разницы нет или что это просто синонимы.
Правильный ответ:
char *arr[3]; — массив из 3 указателей на char (обычно массив строк).char (*arr)[3]; — указатель на массив из 3 char (указатель на одноблочную строку длиной 3).char *arr1[3] = {"a", "bb", "ccc"}; printf("%s", arr1[1]); // bb char str[3] = {'x', 'y', 'z'}; char (*arr2)[3] = &str; printf("%c ", (*arr2)[2]); // z
История 1
В проекте поднимали массив строк для меню, но написали char menu[5][30]; Неверно передали его в функцию параметром как char *menu, из-за чего функции работали только с первой строкой, а остальные искажались или программа падала.
История 2
Попытались создать массив указателей на массивы: int *arr[10]; инициализировали через циклы, но на самом деле хранили указатели на локальные массивы, что вызвало UB при обращении.
История 3
В реализации FIFO-очереди для буферов перепутали, где брать адрес всей очереди (указатель на массив) и где брать элемент (массив указателей на блоки). Из-за этого сдвиги по указателям были некорректны — терялись данные.