Массивы и указатели тесно связаны между собой. Рассмотрим следующий фрагмент:
char str [80], *p1;
p1 = str;
Здесь p1 устанавливается на первый элемент массива str. Если необходимо получить доступ к пятому элементу str, то следует написать
str[4]
или
* (p1 +4)
Оба оператора возвращают пятый элемент. Следует помнить, что индексация массивов начинается с нуля, поэтому для индексации str используется 4. К указателю p1 добавляется 4 для получения пятого элемента, поскольку p1 указывает на первый элемент str. (Надо помнить, что имя массива без индекса возвращает начальный адрес массива, то есть адрес первого элемента.)
С предоставляет два метода доступа к элементам массива. Это важно, поскольку арифметические действия с указателями могут выполняться быстрее, чем индексация массива. Поскольку скорость работы программы часто играет важную роль, использование указателей для доступа к элементам довольно типично в С.
Рассмотрим две упрощенные версии стандартной библиотечной функции puts() для демонстрации данных методов. Один вариант использует индексацию массива, а другой - указатели. Функция puts() выводит строку на стандартное устройство вывода:
/* Использование массива */
int puts (const char *s)
{
register int t;
for(t=0; s [t]; ++t) putchar (s [t]);
return 1;
}
/* использование указателя */
int puts (const char *s)
{
while (*s) putchar (*s++);
return 1;
}
Профессиональные программисты могут найти вторую версию более легкой для чтения и понимания, фактически, версия с указателями демонстрирует типичный способ написания подпрограмм в С.