Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
.doc
Скачиваний:
4
Добавлен:
23.09.2019
Размер:
440.83 Кб
Скачать

23) Указательные выражения. Адресная арифметика. (в1б23, в2б22)

Указательные выражения

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

Пример:

{

int x = 10;

int *p, *g; // объявление указателя

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

g = p; // указатель g тоже указывает на x

printf("p = %d", p); // вывод на экран содержимого p (вывод адреса)

printf("\n g = %d", g); // вывод адреса

printf("\n x = %d", x, "*g = %d", *g); /* вывод на экран величины x и величины, находящейся по адресу указателя g */

}

В языке С допустимо прмсвоить указателю любой адрес памяти. Однако, если объявлен указатель на целое число (int *p;), а по адресу, которому присвоен данному указателю, находится переменная x типа float, то при компиляции программы будет выдано сообщение об ошибке в строке p = &x. Эту ошибку можно исправить, преобразовав указатель на int к типу указателя на float явным преобразованием типа:

p = (int*)&x;

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

Адресная арифметика

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

Пример:

int *ptr, a[10];

ptr=&a[5];

ptr++; // равно адресу элемента a[6]

ptr--; // равно адресу элемента a[5]

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

Пример:

int *ptr1, *ptr2, a[10];

int i=2;

ptr1=a+(i+4); // равно адресу элемента a[6]

ptr2=ptr1-i; // равно адресу элемента a[4]

В операции вычитания могут участвовать два указателя на один и тот же тип. Результат такой операции имеет тип int и равен числу элементов исходного типа между уменьшаемым и вычитаемым, причем если первый адрес младше, то результат имеет отрицательное значение.

Пример:

int *ptr1, *ptr2, a[10];

int i;

ptr1=a+4;

ptr2=a+9;

i=ptr1-ptr2; // равно 5

i=ptr2-ptr1; // равно -5

Значения двух указателей на одинаковые типы можно сравнивать в операциях ==, !=, <, <=, >, >= при этом значения указателей рассматриваются просто как целые числа, а результат сравнения равен 0

(ложь) или 1 (истина).

Пример:

int *ptr1, *ptr2, a[10];

ptr1=a+5;

ptr2=a+7;

if (prt1>ptr2) a[3]=4;

В данном примере значение ptr1 меньше значения ptr2 и поэтому оператор a[3]=4 не будет выполнен.

24) Связь массивов и указателей (в1б24,в3б6)

Принято, что имя массива – адрес памяти, начиная с которого расположен массив, т.е. адрес первого элемента массива.

Идентификатор массива является константным указателем на его нулевой элемент. Например, для массива имя – это тоже самое, что &b[0], а к i-тому элементу массива можно обратиться, используя выражение *(b+i).

Для того, чтобы получить значение 6 элемента массива а, можно записать a[5] или *(a+5). Можно описать указатель, присвоить ему адрес начала массива и работать с массивом через указатель.

Следующий фрагмент программы копирует все элементы массива a в массив b:

int a[100], b[100];

int *pa = a; // или int *p = &a[0]

int *pb = b;

for (int i=0; i<100; i++)

*pb++ = *pa++; // или pb[i] = pa[i]

Для доступа к элементу многомерного массива указываются все его индексы *(matr[i]+j) или *(*(matr[i])+j). Это возможно, поскольку matr[i] является адресом начала строки массива.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]