Идея использования адресов в программах очень стара. Самые первые программисты имели хорошее представление об адресном пространстве программы. Написанные ими программы на машинном языке или языке ассемблера выполняли непосредственные и эффективные пересылки данных, расположенных по одному адресу, в другую адресуемую область.
При появлении языков более высокого уровня программисту был предоставлен высший уровень абстракции. Удобные средства, такие как имена переменных, индексирование массивов, функции и подпрограммы, освободили программиста от необходимости думать на низком уровне машинных адресов.
Язык Си предлагает лучшее из обоих подходов. Язык Си дает возможность манипулировать адресами посредством переменных типа указатель. Эффективность и гибкость, предоставляемая указателями, в сочетании с высокой мобильностью языка Си -- вот две причины частого использования языка Си вместо машинного языка или языка ассемблера там, где наиболее важна скорость выполнения программы.
Указатель — это переменная, содержащая адрес.
Указатель должен быть объявлен также, как объявляются обычные переменные, но перед идентификатором должен стоять символ *.
Пример 1
int          *p_i;   /* указатель на целое типа int*/
float        *p_f;   /*указатель на вещественное типа float */
struct  str  *p_s;   /*указатель на структуру  str*/
Для корректного использования адресной арифметики важно объявлять указатель на тот тип данных, с которым он будет использоваться в программе.
Для чего используются указатели?