Если объявить
int mas[100], *р, а;
то:
1) для массива отводится память в адресном пространстве под 100 элементов типа int.
2) память отводится под указатель-константу с именем MAS, значением указателя является адрес массива.
3) память отводится под указатель-переменную с именем р.
Операция инициализации указателя может осуществляться только операцией "присвоить адрес некоторой переменной".
p = &a;
p = &mas[0]; или p = mas;
или присвоением p = NULL;, где NULL - константа, определенная через define в файле NULL.H.
Допустимо р=0, но не рекомендуется.
Ошибкой являются:
а=10;
р=а; // где р - указатель. Присвоение невозможно, т.к. типы int* и int.
p=10; // присвоение невозможно, т.к. типы int* и const int.
Указателю нельзя присваивать целые значения, но можно складывать и вычитать указатель и целые числа.
р+=10; - экв. р = р+10; - увеличение адреса на 10* масштабный множитель.
р-=2; уменьшение на 2* масшт. множителя.
р+=10; увеличивает на 10 содержимое ячейки, на которую ссылается р.
Например:
Если р=mas; то р+=10; эквивалентно р=р+10 и эквивалентно присвоению р=&mas[10];
*р+=10; эквивалентно mas[0]=mas[0]+10;
Если 2 указателя ссылаются на элементы одного и того же массива, то допускаются операции отношения над ними: = =; !=; <, >, и т.д.
Для указателей, ссылающихся на элементы разных массивов, результат сравнения не определен.
Допускается вычитание указателей.
Например, разработаем функцию вычисления длины строки:
int strlen(char *s)
{ char *p = s; // объявлен указатель и инициирован адресом // массива символов.
While(*p! = '\0') p++;