КОМПЬЮТЕРНАЯ ЛИТЕРАТУРА

Turbo C++ Version 1.0 Programmer’s Guide

Комментировать

LIB.com.ua [электронная библиотека]: : TURBO C++ Version 1.0 Programmer’s Guide

ких значений. В С++ это указатель функции, не принимающей
никаких аргументов и не возвращающей никаких значений. В
примере

void(*func)(int);

*func это указатель функции, принимающей аргумент int и
не возвращающей никаких значений.

Объявления указателей

Подробное описание типа void см. на стр.39 оригинала.

Объявление указателя всегда должно устанавливать его на
некоторый конкретный тип, даже если этот тип void (что фак-
тическиозначает указатель на любой тип). Однако, уже после
объявления указатель обычно может быть переназначен на объ-
ект другого типа. Turbo C++ позволяет переназначать указате-
ли без приведения в соответствие типа, но компилятор выдаст
при этом предупреждение, если только первоначально указатель
не был объявлен с типом void. В С (но не в С++) вы можете
назначить указатель void* на указатель, не имеющий тип
void*.

Если type есть любой предопределенный или определенный
пользователем тип, включая void, то объявление

type *ptr;/* Опасно — неинициализированный указатель */

— 55 —
объявит ptr как «указатель на тип type». К объявленному
таким образомобъекту ptr применимы все правила, связанные с
контекстом, продолжительностью и видимостью.

Указатель со значением null это адрес, гарантированно
отличный от любого допустимого указателя, используемого в
программе. Присвоение указателю целой константы 0 присваива-
ет указателю значение null.

Указатель типа «указатель на void» не следует путать с
нулевым (null) указателем. Объявление

void *vptr;

объявляет, что vptr — это родовой указатель, которому-
может быть присвоено любое значение «указатель на тип type»
без выдачи компилятором сообщений. Присвоения без правильно-
го приведения типов между «указателем на тип type1» и «ука-
зателем на тип type2», где type1 и type2 это различные типы,
может вызвать предупреждение или ошибку компилятора. Если
type1 это функция, а type2 нет (или наоборот), присваивания
указателей недопустимы. Если type1 это указатель на void,
приведения типов не требуется. Если type2 это указатель на
тип void, то в С приведение не нужно.

Ограничения присвоения также существуют относительно
указателей разных размеров (near, far и huge). Можно присво-
ить меньший указатель большему, не вызвав ошибки, но нельзя
выполнить обратную операцию, не выполнив явную операцию при-
ведения. Например,

char near *ncp;
char far *fcp;
char huge *hcp;
fcp = ncp; // допустимо
hcp = fcp; // допустимо
fcp = hcp; // недопустимо
scp = fcp; // недопустимо
scp = (char nesr*)fcp; // теперь допустимо
Указатели и константы

Указатели или указываемые ими объекты могут быть объяв-
лены с модификатором const. Присвоение объекту, объявленно-
мукак const, не допускается. Также не допускается создание
указателя, который может нарушить запрещение на модификацию
объекта типа константы. Рассмотрим следующие примеры:

int i; // i это целое;
int * pi; // pi это указатель на i
// (неинициализированный)
int * const cp = &i; // cp это указатель-константа на int
// const
int ci = 7; // ci это константа int const
int * pci; // pci это указатель наконстанту ci
const int * const cpc = &ci; // cpc это указатель-конс-
танта
// на константу int

Следующие присвоения допустимы:

i = ci; // Присвоить const int переменной int
*cp = ci; // Присвоение const int объекту, на
// который указывает
// указатель-константа
++pci; // Инкремент указателя на константу
pci = cpc; // Присвоение константы-указателя-на

// константу указателю-на-константу

— 56 —

Следующие присвоения недопустимы:

ci = 0; // Присвоение значений константе
// const int недопустимо
ci—; // Изменение константы недопустимо
*pci = 3; // Присвоение объекту, на который
// указывает указатель-на-константу
// недопустимо
cp = &ci; // Присвоение константе-указателю,
// даже если ее значение не будет
// изменено, недопустимо
cpc++; // Изменять указатель-константу
// недопустимо
pi = pci; // Если бы такое присвоение было
// разрешено, вы могли бы присваивать
// *pci (константе), присваивая *pi
// что недопустимо

Аналогичные правила относятся и к модификатору
volatile.Отметим, что const и volatile могут появляться в
качестве модификаторов одного и того же идентификатора.

Арифметические операции с указателями

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

Арифметические операции с указателями ограничены
сложением, вычитанием и сравнением. Арифметические операции
с указателями объектов типа «указатель на тип type» автома-
тически учитывают размер этоготипа, то есть число байт, не-
обходимое для хранения в памяти объекта данного типа.

При выполнении арифметических операций с указателями
предполагается, что указатель указывает на массив объектов.
Таким образом, если указатель объявлен как указатель на
type, то прибавление к нему целочисленного значения переме-
щает указатель на соответствующее количество объектов type.
Если type имеет размер 10 байтов, то прибавление целого чис-
ла 5 к указателю этого типа перемещает указатель в памяти на
50 байт. Разность представляет собой число элементов масси-
ва, разделяющих два значения указателей. Например, если ptr1
указывает на третий элемент массива, а ptr2 на десятый, то
результатом выполнения вычитания ptr2 — ptr1 будет 7э

Когда с «указателем на тип type» выполняется операция
сложения или вычитание целого числа, то результат также бу-
дет «указателем на тип type». Ецли type неявляется массивом,
то операнд указателя будет рассматриваться как указатель на
первый элемент «массива типа type» длиной sizeof(type).

Конечно, такого элемента, как «указатель на следующий
за последним элемент», однако указатель может принимать это
значение. Если P указывает на последний элемент массива, то
значение P+1 допустимо, но P+2 неопределено. Если P указыва-
ет на элемент за последним элементом массива, то допустимо
значение P-1, когда указатель установлен на последний эле-
мент массива. Однако установка указателя на элемент за пос-
ледним элементом массива ведет к непредсказуемым результатам
работы программы.

Для информации:P+n можно представить себе как перемеще-
ние указателя на (n*sizeof(type)) байт вперед, пока указа-

— 57 —
тель остается в допустимых границах (не далее первого за
концом массива элемента).

Вычитание междудвумя указателями на элементы одного и
того же массива дает интегральное значение типа ptrdiff_t,
определенное в stddef.h (signed long для указателей huge и
far; signed intдля всех прочих). Данное значение представля-
ет собой разность между индексами двух указанных элементов,
при условии вхождения в диапазоне ptrdiff_t. В выражении
P1P2, где P1 и P2 это указатели на тип type (или указатели
на квалифицированный тип), P1 и P2 должны указывать на су-
ществующие элементы или на следующий за последним элемент.
если P1 указывает на i-й элемент, а P2 указывает на j-й эле-
мент, то P1-P2 имеет значение (i-j).

Преобразования указателей

Указатели одного типа могут бытьпреобразованы в указа-
тели другого типа при помощи следующего механизма приведения
типов:

char *str
int *ip
str = (char*)ip;

В более общем виде, приведение (type*) преобразует ука-
затель в тип «указатель на тип type».

Объявления ссылок в С++

Ссылочные типы С++ тесно связаны с типами указателей.

Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *