Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ЯП - ПОИТ (Бахтизин) часть 1 редакт.doc
Скачиваний:
2
Добавлен:
01.04.2025
Размер:
1.76 Mб
Скачать

2) Косвенная адресация или разыменование указателя

Так как указатель содержит адрес объекта, то это дает возможность «косвенного» доступа к этому объекту через указатель.

Операция * называется операцией косвенной адресации. Она возвращает значение переменной, на которую ссылается указатель.

Например:

int x = 10; // объявление переменной целого типа и

// её инициализация значением «10»

int *p; // объявление указателя на переменную целого типа

p = &x; // присваивание указателю p адреса переменной x

*p = 5; // присваивание переменной x значения 5

*p = *p*2; // присваивание переменной x значения 10

Рис.4.3. Указатель на переменную целого типа

Оба оператора выводят значение переменной x:

  1. Без использования указателя

printf(“%d”, x);

2) С использованием указателя

printf(“%d”, *p);

К указателям может применяться определенный набор арифметических операций. В качестве примера определим массив int a[10], первый элемент которого будет иметь адрес в памяти, равный 3000. Инициализируем указатель p значением адреса элемента a[0], т.е. значение p равно 3000. Этот пример изображен на рис.4.3.

int a[10];

int *p1,*p;

p = &a[0];

Рис. 4.4. Массив a[] и указатель p, ссылающийся на a

3) Увеличение или уменьшение значения указателя на целое число

p = p + i или p = p - i

В арифметике указателей при прибавлении или вычитании из указателя целого числа значение его увеличивается или уменьшается не на это число, а на произведение числа на размер объекта (переменной), на который указывает p, т.е на i*(sizeof (тип)), где тип – это тип данных на которые указывает p.

Например:

int *p;

p=&a[0];

p=p+5; // значение указателя p увеличивается на

// 5*sizeof(int) = 10,

// т.е. p теперь указывает на 6-ой элемент

// массива a;

Соответственно с указателями можно использовать операции инкремента и декремента.

p++; // Установить указатель на переменную, следующую за

// той, на которую указатель указывает в данный момент

p--; // Установить указатель на переменную, предшествующую

// той, на которую указатель указывает в данный момент

Таким образом, физическое увеличение или уменьшение указателя зависит от типа указателя, то есть от размера элемента данных и ячейки памяти, на которую указывает указатель.

4) Разность указателей

Данная операция имеет смысл только тогда, когда указатели ссылаются на элементы одного и того же массива.

Например:

int x;

p1=&a[0];

p2=&a[5];

x=p2-p1;

Разность двух указателей равна разности их значений, поделенной на sizeof (тип), т.е. x=(3010-3000)/2=5 (см. рис.4.4). Переменной x будет присвоено число элементов массива, расположенных, начиная с адреса p1 и до p2, в данном случае это 5.

5) Сравнение указателей

Указатели могут сравниваться друг с другом при помощи операций отношения, но сравнение указателей обычно не имеет смысла, если они не ссылаются на элементы одного и того же массива. При сравнении указателей сравниваются адреса, являющиеся значениями указателей. Сравнение двух указателей, ссылающихся на элементы одного и того же массива, могло бы показать, например, что один указатель ссылается на элемент с большим значением индекса, чем другой указатель.

p1=&c[0];

p2=&c[5];

if (p1>p2) – ложь

Любой указатель можно проверять на равенство или неравенство NULL или 0. Указатель NULL совместим с указателем на любой тип и уникален (т.е. никаких объектов, расположенных по нулевому адресу быть не может).

Пусть, например, объявлен указатель *p.

Выражение p!=0 эквивалентно выражению p!=NULL.