Операции над указателями. Помимо уже рассмотренных операций, с указателями можно выполнять арифметические операции сложения, инкремента (++)

Помимо уже рассмотренных операций, с указателями можно выполнять арифметические операции сложения, инкремента (++), вычитания, декремента (--) и операции сравнения.

Арифметические операции с указателями автоматически учитывают размер типа величин, адре­суемых указателями. Эти операции применимы только к указателям одного типа и имеют смысл в основном при работе со структурами данных, последовательно размещенными в памяти, например с массивами.

Инкремент перемещает указатель к следующему элементу массива, декремент – к предыдущему.

Указатель, таким образом, может использоваться в выражениях вида

p # iv, ## p, p ##, p # = iv,

p – указатель, iv – целочисленное выражение, # – символ операции '+' или '–'.

Результатом таких выражений является увеличенное или уменьшенное значение указателя на величину iv * sizeof(*p), т.е. если указатель на определенный тип увеличивается или уменьшается на константу, его значение изменяется на величину этой константы, умножен­ную на размер объекта данного типа.

Текущее значение указателя всегда ссылается на позицию некоторого объекта в памяти с учетом правил выравнивания для соответствующего типа данных. Таким образом, значение p # iv указывает на объект того же типа, расположенный в памяти со смещением на iv позиций.

При сравнении указателей могут использоваться отношения любого вида («>», «<» и т.д.), но наиболее важными видами проверок являются отношения равенства и неравенства («==», «!=»).

Отношения порядка имеют смысл только для указателей на последовательно размещенные объекты (элементы одного массива).

Разность двух указателей дает число объектов адресуемого ими типа в соответствующем диапазоне адресов, т.е. в применении к массивам разность указателей, например, на третий и шестой элементы равна 3.

Очевидно, что уменьшаемый и вычитаемый указатели должны принадлежать одному массиву, иначе результат операции не имеет практической ценности и может привести к непредсказуемому результату. То же можно сказать и о суммировании указателей.

Значение указателя можно вывести на экран с помощью функции printf, используя спецификацию %p (pointer), результат выводится в шестнадцатеричном виде.

Рассмотрим фрагмент программы:

int a = 5, *p, *p1, *p2;

p = &a;

p2 = p1 = p;

++p1;

p2 += 2;

printf(“a = %d , p = %d , p = %p , p1 = %p , p2 = %p .\n”, a, *p, p, p1, p2);

Результат может быть следующим:

a = 5 , *p = 5 , p = FFF4 , p1 = FFF6, p2 = FFF8 .

Графически это выглядит следующим образом (в 16-разрядном процессоре на тип int отводится 2 байта):

  FFF5 FFF7 FFF9  
  FFF4 р FFF6 p1 FFF8 p2 FFF10  
                   

p = FFF4,

p1 = FFF6 = ( FFF4 + 1*sizeof(*p)) ® FFF4 + 2 (int)

р2 = FFF8 = ( FFF4 + 2*sizeof(*p)) ® FFF4 + 2*2

На одну и ту же область памяти (как видно из приведенного примера), может ссылаться несколько указателей различного типа. Но примененная к ним операция разадресации даст разные результаты.

При смешивании в выражении указателей разных типов явное преобразование типов требуется для всех указателей, кроме void*.

Явное приведение типов указателей позволяет получить адрес объекта любого типа:

type *p;

p = (type*) &object;

Значение указателя p позволяет работать с переменной object как объектом типа type.








Дата добавления: 2015-09-11; просмотров: 669;


Поиск по сайту:

При помощи поиска вы сможете найти нужную вам информацию.

Поделитесь с друзьями:

Если вам перенёс пользу информационный материал, или помог в учебе – поделитесь этим сайтом с друзьями и знакомыми.
helpiks.org - Хелпикс.Орг - 2014-2024 год. Материал сайта представляется для ознакомительного и учебного использования. | Поддержка
Генерация страницы за: 0.006 сек.