Соглашение о нулевых указателях



 

Объявленный, но не инициализированный указатель будет содержать произвольное значение. При попытке использовать указатель до присвоения ему конкретного значения можно разрушить не только собственную программу, но даже и операционную систему (отвратительнейший, надо сказать, тип ошибки!). Поскольку не существует гарантированного способа избежать использования неинициализированного указателя, С++‑программисты приняли процедуру, которая позволяет избегать таких ужасных ошибок. По соглашению, если указатель содержит нулевое значение, считается, что он ни на что не ссылается. Это значит, что, если всем неиспользуемым указателям присваивать нулевые значения и избегать использования нулевых указателей, можно избежать случайного использования неинициализированного указателя. Вам следует придерживаться этой практики программирования.

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

 

 

Для тестирования указателя используется инструкция if (любой из следующих ее вариантов).

 

 

Соблюдая упомянутое выше соглашение о нулевых указателях, вы можете избежать многих серьезных проблем, возникающих при использование указателей.

 

Указатели и 16‑разрядные среды

 

Несмотря на то что в настоящее время большинство вычислительных сред 32‑разрядные, все же немало пользователей до сих пор работают в 16‑разрядных (в основном, это DOS и Windows 3.1) и, естественно, с 16‑разрядным кодом. Эти операционные системы были разработаны для процессоров семейства Intel 8086, которые включают такие модификации, как 80286, 80386, 80486 и Pentium (при работе в режиме эмуляции процессора 8086). И хотя при написании нового кода программисты, как правило, ориентируются на использование 32‑разрядной среды выполнения, все же некоторые программы по‑прежнему создаются и поддерживаются в более компактных 16‑разрядных средах. Поскольку некоторые темы актуальны только для 16‑разрядных сред, программистам, которые работают в них, будет полезно получить информацию о том, как адаптировать "старый" код к новой среде, т.е. переориентировать 16‑разрядный код на 32‑разрядный.

При написании 16‑разрядного кода для процессоров семейства Intel 8086 программист вправе рассчитывать на шесть способов компиляции программ, которые различаются организацией компьютерной памяти. Программы можно компилировать для миниатюрной, малой, средней, компактной, большой и огромной моделей памяти. Каждая из этих моделей по‑своему оптимизирует пространство, резервируемое для данных, кода и стека. Различие в организации компьютерной памяти объясняется использованием процессорами семейства Intel 8086 сегментированной архитектуры при выполнении 16‑разрядного кода. В 16‑разрядном сегментированном режиме процессоры семейства Intel 8086 делят память на 16К сегментов.

В некоторых случаях модель памяти может повлиять на поведение указателей и ваши возможности по их использованию. Основная проблема возникает при инкрементировании указателя за пределы сегмента. Рассмотрение особенностей каждой из 16‑разрядных моделей памяти выходит за рамки этой книги. Главное, чтобы вы знали, что, если вам придется работать в 16‑разрядной среде и ориентироваться на процессоры семейства Intel 8086, вы должны изучить документацию, прилагаемую к используемому вами компилятору, и подробно разобраться в моделях памяти и их влиянии на указатели.

И последнее. При написании программ для современной 32‑разрядной среды необходимо знать, что в ней используется единственная модель организации памяти, которая называется одноуровневой, несегментированной или линейной (flat model).

 

Многоуровневая непрямая адресация

 

Можно создать указатель, который будет ссылаться на другой указатель, а тот – на конечное значение. Эту ситуацию называют многоуровневой непрямой адресацией (multiple indirection) или использованием указателя на указатель. Идея многоуровневой непрямой адресации схематично проиллюстрирована на рис. 6.2. Как видите, значение обычного указателя (при одноуровневой непрямой адресации) представляет собой адрес переменной, которая содержит некоторое значение. В случае применения указателя на указатель первый содержит адрес второго, а тот ссылается на переменную, содержащую определенное значение.

 

 

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

Переменную, которая является указателем на указатель, нужно объявить соответствующим образом. Для этого достаточно перед ее именем поставить дополнительный символ "звездочка"(* ). Например, следующее объявление сообщает компилятору о том, что balance – это указатель на указатель на значение типа int .

 

 

Необходимо помнить, что переменная balance здесь – не указатель на целочисленное значение, а указатель на указатель на int‑значение.

Чтобы получить доступ к значению, адресуемому указателем на указатель, необходимо дважды применить оператор "*" как показано в следующем коротком примере.

 

 

Здесь переменная p объявлена как указатель на int‑значеине, а переменная q – как указатель на указатель на int‑значеине. При выполнении этой программы мы получим значение переменной х , т.е. число 10 .

 


Дата добавления: 2018-09-22; просмотров: 358; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!