16 Указатели и адресная арифметика в языках программирования высокого уровня Указатель - это переменная, содержащая адрес другой переменной. Указатели - "фамильная" принадлежность языка C. При описании указателя надо задать тип объектов, адреса которых будут содержаться в нем. Перед именем указателя при оеписании ставится звездочка, чтобы отличить его от обычной переменной. Пример описания указателей: int *a, *b, c, d; //указатели a и b на тип int и простые переменные c и d, - c и d не указатели! char *e; void *f; С указателями возможны следующие два действия: 1) Присвоить указателю адрес некоторой переменной. Для этого используется операция взятия адреса, которая обозначается амперсандом & Например: a = &c; 2) Получить значение переменной, адрес которой содержится в указателе; для этого используется операция звездочка '*' - операция разадресации, которая записывается перед указателем. Например: d = *a; //присваевает переменной d значение целочисленной переменной, адрес которой содержится в а. Т.к. ранее указателю a был присвоен адрес переменной c, то в результате переменной d присваивается значение с, т.е. данная строка эквивалентна следующей: d = c; Указатели могут входить в выражения. Например: d = *a + 1; //присваевает d значение, на 1 большее значение c cout << *a; //печатает текущее значение c Т.к. указатели являются перепенными, то с ними можно обращаться, как с остальными переменными. Если b - другой указатель на переменную типа INT то: b = a; // копирует содержимое a в b в результате чего b указывает на то-же что и а, т.е. на c. int A[10]; //определяет массив из 10 целочисленных элементов. Если pA -указатель на целое, описанный как int *pA; то присваивание pA = &A[0]; приводит к тому, что pA указывает на первый элемент массива А; Это означает, что pA содержит адрес элемента А[0]. После этого присваивание d = *pA; будет копировать содержимое A[0] в d; Арифметика указателей С указателями можно выполнять следующие операции: - сложение указателя и целого числа, результат - указатель; - автоувеличение или автоуменьшение переменной типа указатель, что эквивалентно прибавлению или вычитанию единицы; - вычитание двух указателей, результат - целое число; int *p, *q; int a[100]; p = &(a[5]); // записываем в p адрес 5-го элемента массива а p += 7; // р будет содержать адрес 12-го элемента q = &(a[10]); --q; // q содержит адрес элемента а[9] Значение указателя при прибавлении к нему целого числа n увеличивается на произведение n на количество байтов, занимаемое одним элементов того типа, на который ссылается указатель. В программировании это называется масштабированием. Разность двух указателей - это количество элементов данного типа, которое умещается между двумя адресами. Результатом вычитания указателей является целое число. Физически оно вычисляется как разность значений двух адресов, деленная на размер одного элемента заданного типа. Операции сложения указателя с целым числом и разности двух указателей взаимнообратны int *p, *q; int a[100]; int n; p = &(a[5]); q = &(a[12]); n = q - p; // n == 7 q = p + n; // q == 7(a[12]) УКАЗАТЕЛИ НЕЛЬЗЯ СКЛАДЫВАТЬ! В отличии от разности, операция сложения абсолютно бессмысленна. int *p, *q, *r; int a[100]; p = &(a[5]); q = &(a[12]); r = p + q; // ошибка! указатели нельзя складывать