Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
c++book1.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
2 Мб
Скачать
☆

2.4.5 Ноль

Ноль можно употреблять как константу любого целого, пла­вающего или указательного типа. Никакой объект не размещается по адресу 0. Тип нуля определяется контекстом. Обычно (но не обязательно) он представляется набором битов все-нули соот­ветствующей длины.

2.4.6 Const

Ключевое слово const может добавляться к описанию объек­та, чтобы сделать этот объект константой, а не переменной. Например:

const int model = 145;

const int v[] = (* 1, 2, 3, 4 *);

Поскольку константе ничего нельзя присвоить, она должна быть инициализирована. Описание чего-нибудь как const гаран­тирует, что его значение не изменится в области видимости:

model = 145; // ошибка

model++; // ошибка

Заметьте, что const изменяет тип, то есть ограничивает способ использования объекта, вместо того, чтобы задавать способ размещения константы. Поэтому например вполне разумно, а иногда и полезно, описывать функцию как возвращающую const:

const char* peek(int i)

(*

return private[i];

*)

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

С другой стороны, компилятор может несколькими путями воспользоваться тем, что объект является константой (конечно, в зависимости от того, насколько он сообразителен). Самое очевидное - это то, что для константы не требуется выделять память, поскольку компилятор знает ее значение. Кроме того, инициализатор константы часто (но не всегда) является конс­тантным выражением, то есть он может быть вычислен на стадии компиляции. Однако для вектора констант обычно приходится вы­делять память, поскольку компилятор в общем случае не может вычислить, на какие элементы вектора сделаны ссылки в выраже­ниях. Однако на многих машинах даже в этом случае может дос­тигаться повышение эффективности путем размещения векторов констант в память, доступную только для чтения.

Использование указателя вовлекает два объекта: сам ука­затель и указываемый объект. Снабжение описания указателя "префиксом" const делает объект, но не сам указатель, конс­тантой. Например:

const char* pc = "asdf"; // указатель на константу

pc[3] = 'a'; // ошибка

pc = "ghjk"; // ok

Чтобы описать сам const указатель, а не указываемый объ­ект, как константный, используется операция const*. Например:

char *const cp = "asdf"; // константный указатель

cp[3] = 'a'; // ok

cp = "ghjk"; // ошибка

Чтобы сделать константами оба объекта, их оба нужно опи­сать const. Например:

const char *const cpc = "asdf"; // const указатель на const

cpc[3] = 'a'; // ошибка

cpc = "ghjk"; // ошибка

Объект, являющийся константой при доступе к нему через один указатель, может быть переменной, когда доступ осущест­вляется другими путями. Это в частности полезно для парамет­ров функции. Посредством описания параметра указателя как const функции запрещается изменять объект, на который он ука­зывает. Например:

char* strcpy(char* p, const char* q); // не может изменить q

Указателю на константу можно присваивать адрес перемен­ной, поскольку никакого вреда от этого быть не может. Однако нельзя присвоить адрес константы указателю, на который не бы­ло наложено ограничение, поскольку это позволило бы изменить значение объекта. Например:

int a = 1;

const c = 2;

const* p1 = &c; // ok

const* p2 = &a; // ok

int* p3 = &c; // ошибка

*p3 = 7; // меняет значение c

Как обычно, если тип в описании опущен, то он предпола­гается int.

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