Процедурное программирование на языке С. Часть 1. Основные понятия языка С: Методические указания к лабораторным работам по курсам «Алгоритмические языки и программирование» и «Процедурное программирование», страница 10

Запись/взятие значения по адресу, который хранится в переменной p, выполняется следующим образом. Запись значения по адресу, который хранится в переменной с именем p, выполняется в операторе присваивания, причем выражение *p – левая часть этого оператора. При этом важно соответствие типов, т.е. значение, записываемое по адресу, и результат выражения правой части оператора должны иметь одинаковые типы.

Взятие значения по адресу, который хранится в переменной с именем p, выполняется в операторе присваивания, при этом выражение *p – часть  выражения в правой части этого оператора. При этом также важно соблюдать соответствие типов. Допускаются необходимые преобразования типов.

С помощью операций адресной арифметики можно изменять значения переменных-указателей.

Замечание. Речь пойдет об изменении значений переменных типа указатель, но никак не адресов в оперативной памяти.

1. Допускается сложение переменной типа указатель с целым числом. Однако результат этой операции зависит не только от числа, а главным образом от типа данных, на которые ссылается указатель.

Пусть объявлены переменная name и переменная-указатель pointer с инициализацией:

        <спецификация типа >  name; 

        <спецификация типа >  *  pointer = &name;

Тогда справедлива формула 1:

pointer+j =  pointer + j*sizeof(<спецификация типа >), где значение переменной j  некоторое целое число.

2. Аналогично выполняется операция вычитания некоторого целого числа из переменной типа указатель.

3. С помощью унарных операций ‘++’ и ‘--’ числовые значения переменных типа указатель меняются по-разному в соответствии с формулой 1 при  j = 1.

4. Операция вычитания ‘ – ’ может применяться к двум переменным – указателям на объекты одного типа. Эта операция позволяет определить расстояние между размещением в памяти двух объектов одного типа. Расстояние вычисляется в единицах, кратных длине участка памяти, занимаемого одним объектом, для хранения адреса которого объявляются указатели. 

Пусть объявлены переменные k и j как переменные типа int, объявлен массив с именем mas и переменные-указатели pointer1 и pointer2 :

            <спецификация типа >  mas[23]; 

            <спецификация типа >  pointer1 = mas, *  pointer2 ;

После вычисления значения переменной k указатель pointer2 инициализируется

pointer2 = & mas[k]; 

Тогда  справедлива формула 2:

j = pointer2 –   pointer1 = ( pointer2 –   pointer1)/sizeof(<спецификация типа >),

при этом значение переменной  j совпадет со значением переменной k.

5. Операцию сложения, как и операции умножения и деления, нельзя применять к двум переменным – указателям, т.к. результат этих операций смысла не имеет.

6.  Переменные-указатели можно использовать в отношениях, т.е. к ним применяются все операции сравнения.

3.3. СПОСОБЫ ДОСТУПА К ЭЛЕМЕНТАМ МАССИВА

В языке С между указателями и массивами существует тесная связь. Для доступа к элементам массива существует два способа.

·  Первый способ связан с использованием обычных индексных выражений в квадратных скобках. Синтаксическая форма для первого способа:

<имя указателя>[<выражение>],  причем при таком способе доступа квадратные скобки – обязательный атрибут, а значением выражения в квадратных скобках должно быть целое число.

Например, mas [1]=3;  или {  i = 0;   mas [i+2]=7; }.

·  Второй способ доступа к элементам массива связан с использованием адресных выражений и операции взятия значения по адресу. Синтаксическая форма для второго способа:

 *  (<имя указателя> + <выражение>) , 

                         операция взятия значения по адресу (синонимы:                                                                         раскрытие ссылки, разыменование, разадресация).

Причем и при таком способе доступа значением выражения в скобках должно быть целое число.