Проблемы, связанные с использованием указателей

Указатели придают мощь и изящность программному коду. Кроме того, они необходимы в большинстве программ. Но когда указатель содержит неправильное значение, он может вызвать наиболее трудно устранимую ошибку. Сам по себе указатель не вызывает никаких проблем. Проблемы возникают, когда выполняется какая-либо операция, использующая неправильный указатель, например, производится чтение или запись в неизвестный участок памяти. При чтении в худшем случае в результате будет прочитан «мусор». При записи можно затереть участки кода или данных. В результате этого при поиске ошибки можно найти ее совсем в другом месте. Не существует очевидного способа для разрешения проблем, связанных с указателями.

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

Классическим примером ошибки с указателем является неинициализированный указатель. Например:

// программа некорректна

void main (){

int x, *p;

x = 10;

*p = x;

}

Данная программа присваивает значение 10 некоторому неизвестному участку памяти. Указатель p не получал адреса памяти, которую можно использовать. Следовательно, он содержит неопределенное значение. Такого рода проблемы часто незаметны, когда программа невелика, поскольку p, скорее всего, содержит «безопасный» адрес, не принадлежащий коду, данным, стеку или операционной системе. По мере роста программы растет и вероятность того, что неправильное использование указателя испортит жизненно важную часть программы. Неожиданно программа может зависнуть. Направление решения таких проблем совершенно очевидно: следует убедиться, что указатель указывает на некоторую допустимую область. Хотя в таких случаях ошибки достаточно непросто обнаружить: частая инициализация указателей (или некорректная инициализация) затрудняет поиск ошибок.

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

// программа некорректна

void main (){

int x, *p;

x = 10;

p = x;

printf("%d",*p);

}

Вызов printf() не выводит значения x, которое равно 10, на экран. В результате возникает ошибка из-за неправильного оператора присваивания

p = x;

Этот оператор присваивает значение 10 указателю р, который должен содержать адрес, а не значение. Для устранения ошибки следует написать

p = &x;

Хотя С++ выдает предупреждения об ошибках в программе, они не всегда могут помочь. Данные типы ошибок могут потребовать окольных путей по их обнаружению. Поэтому следует быть внимательным. Тот факт, что указатели могут вызвать очень сложные ошибки при некорректном использовании, не имеет никакого отношения к устранению этих ошибок.

Ключевые термины

Многочисленное перенаправление –это адресация указателем адреса другого указателя, что в конечном итоге сводится к адресации участка памяти.

Необязательные параметры –это неизвестные на момент компиляции параметры в прототипе функции.

Обязательные параметры –это известные на момент компиляции параметры в прототипе функции.

Одиночное перенаправление –это адресация указателем некоторого участка памяти.

Указатель на указатель –это указатель, реализующий многочисленное перенаправление.

Функции с переменным числом параметров –это функции, полный список параметров у которых может быть неизвестен на момент компиляции программы.

Краткие итоги

1.Указатель может реализовать одиночное или многочисленное перенаправление в зависимости от его объявления.

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

3.В языке С++ предусмотрены объявление и вызов функций с переменным числом параметров.

4.В прототипе функции с переменным числом параметров описываются спецификации обязательных параметров, список необязательных параметров обозначается многоточием.

5.Для функций с переменным числом параметров существуют два основных способа контроля количества параметров в списке: через передачу количества параметров и по признаку конца списка параметров.

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

Набор для практики

Вопросы

1. С какой целью в программах используют указатели на указатели?

2. Что будет являться результатом однократной операции разыменования указателя, реализующего многочисленное перенаправление?

3. Для чего в программе необходима инициализация указателя перед первым его использованием?

4. С какой целью в прототипах функций с переменным числом параметров должны быть указаны обязательные параметры?

5. Как в функции с переменным числом параметров осуществляется доступ к списку неизвестных параметров?

6. Почему для доступа к списку неизвестных параметров достаточно знать адрес хотя бы одного обязательного параметра?

7. Почему ошибки, связанные с некорректным использованием указателей, относятся к наиболее трудноустранимым?

Упражнения

1.Наберите коды программ из Примеров 1-2. Выполните компиляцию и запуск программ.

2.Напишите функцию, параметрами которой служат адреса трех переменных типа double. Функция должна возвращать адрес (значение указателя) той из переменных, адресуемых параметрами, которая имеет максимальное значение. В основной программе с помощью обращения к функции поменяйте знак значения максимальной из трех переменных. Для решения данной задачи используйте вспомогательную функцию, возвращающую адрес максимальной из переменных, адресуемых двумя параметрами-указателями.

3.Напишите функцию для вычисления значения многочлена Проблемы, связанные с использованием указателей - student2.ru Коэффициенты Проблемы, связанные с использованием указателей - student2.ru , аргумент Проблемы, связанные с использованием указателей - student2.ru и коэффициенты передавайте в функцию с помощью списка параметров изменяемой длины. В основной программе вычислите и напечатайте значения нескольких полиномов. Для вычисления полиномов используйте схему Горнера:

Проблемы, связанные с использованием указателей - student2.ru .

4.Напишите функцию, которая упорядочивает значение трех переменных, адреса которых передаются ей в качестве параметров. В основной программе продемонстрируйте применение написанной функции. Для решения данной задачи определите и используйте вспомогательную функцию, которая упорядочивает значения только двух переменных, адресуемых ее двумя аргументами.

5.Напишите функцию с переменным числом параметров в соответствии с заданием, продемонстрировать вызов функции с различным числом параметров. Выполните вычисления для трех и десяти чисел. Решите задачу двумя способами: через передачу количества параметров как параметр функции и через использование признака конца списка параметров. В задаче требуется найти среднее гармоническое элементов числового ряда.

Литература

1. Керниган, Б. Язык программирования Си / Б. Керниган, Д. Ритчи. – М.: Вильямс, 2007. – 304 с.

2. Подбельский, В.В. Практикум по программированию на языке Си: учеб. пособие / В.В. Подбельский. – М.: Финансы и статистика, 2004. – 576 с.

3. Подбельский, В.В. Программирование на языке Си: учеб. пособие / В.В. Подбельский, С.С. Фомин. – М.: Финансы и статистика, 2004. – 600 с.

4. Подбельский, В.В. Язык Си++: учеб. пособие / В.В. Подбельский. – М.: Финансы и статистика, 2005. – 560 с.

5. Романов, Е.Л. Практикум по программированию на языке С++: учеб. пособие / Е.Л. Романов. – СПб: БХВ-Петербург, 2004. – 432 с.

6. С/С++. Структурное программирование: практикум / Т.А. Павловская, Ю.А. Щупак. – СПб: Питер, 2004. – 239 с.

Наши рекомендации