Отладка программ

otladkdddddd.jpgОтладка — этап разработки компьютерной программы, на котором обнаруживают, локализуют и устраняют ошибки.

Типы ошибок

  • ошибки компиляции
  • ошибки выполнения
  • логические ошибки

Ошибки компиляции

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


Ошибки выполнения

Другой тип ошибок - ошибки выполнения программы или семантические ошибки. Они встречаются, когда пользователь компилирует синтаксически корректную программу, которая пытается сделать что-нибудь запрещенное во время ее выполнения, например, открывает несуществующий файл для ввода или производит деление на 0.


Логические ошибки

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


Существуют две взаимодополняющие технологии отладки.

Вот что пишут об этих двух подходах к отладке программы Брайан Керниган и Роб Пайк:


«Наш личный выбор — стараться не использовать отладчики, кроме как для просмотра стека вызовов или же значений пары переменных. Одна из причин этого заключается в том, что очень легко потеряться в деталях сложных структур данных и путей исполнения программы. Мы считаем пошаговый проход по программе менее продуктивным, чем усиленные размышления и код, проверяющий сам себя в критических точках.

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

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

«Отладка сложна и может занимать непредсказуемо долгое время, поэтому цель в том, чтобы миновать большую её часть. Технические приёмы, которые помогут уменьшить время отладки, включают хороший дизайн, хороший стиль, проверку граничных условий, проверку правильности исходных утверждений и разумности кода, защитное программирование, хорошо разработанные интерфейсы, ограниченное использование глобальных переменных, автоматические средства контроля и проверки. Грамм профилактики стоит тонны лечения.»

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

  • Вывод текущего состояния программы с помощью расположенных в критических точках программы операторов вывода — на экран, принтер, громкоговоритель или в файл. Вывод отладочных сведений в файл называется журналированием.

Отладка с использованием отладчика в программных средах:

Pascal

Интегрированный отладчик Turbo Pascal

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

Интегрированный отладчик Turbo Pascal имеет все описанные выше возможности и даже более того. Он представляет собой встроенную часть интегрированной усовершенствованной среды Turbo Pascal (IDE): для использования предлагаются две основные функции меню (Run, Debug), а также некоторые клавиши для команд отладчика.

Более подробно об отладке программ в среде Pascal можно посмотреть здесь: http://www.realcoding.net/article/view/748


Visual Studio

Разработчики Visual Studio постарались как можно сильнее упростить процесс отладки. И ввели «упрощенную отладку» с множеством возможностей. О них можно прочитать здесь http://msdn.microsoft.com/ru-ru/beginner/aa700762.aspx

Отладка в среде C++:http://www.devdoc.ru/index.php/content/view/debugging_p2.htm

Описание технологии отладки на примере Visual Studio C#

В данном разделе я попробую описать процесс отладки программы, написанной в среде «Visual Studio C# 2008 Express Edition». Все ошибки в коде программы, которые я сам же буду находить сделаны специально.

Цель: Разработать и отладить программу «АйСчитайка», которая будет производить поиск корней квадратного уравнения.

Разработка:

1)создаём новый проект

2)пишем пользовательский интерфейс

3)пишем сам код программы.

Спустя 10 минут я получил:

     {
          integer a, b, c;           
          X11.Visible = false;
          X22.Visible = false;
          XX.Visible = false;
          xx1.Visible = false;
          xx1.Visible = false;
          xx2.Visible = false;
          neet.Visible = false;
          primer.Visible = false;
          a = Convert.ToInt32(aa.Value);
          b = Convert.ToInt32(bb.Value);
          c = Convert.ToInt32(cc.Value)
          double d = b * b + 4 * a * c;
          if d > 0
          {
              X11.Visible = true;
              X22.Visible = true;
              double x1 = (b + Math.Sqrt(d)) / 2 * a;
              double x2 = (b - Math.Sqrt(d)) / 2 * a;
              xx1.Visible = true;
              xx2.Visible = true;
              xx1.Text = x1.ToString();
              xx2.Text = x2.ToString();
          }
          if (d < 0)
          {
              neet.Visible = true;
              neet.Text = "нет корней"
          }
          if (d == 0)
          {
              XX.Visible = true;
              neet.Visible = true;
              double x = (-b / 2 * a);
              neet.Text = x.ToString();
          }
          primer.Text = a + "X^2+" + b + "X+" + c + "=0";
          primer.Visible = true;
      }

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

ne_skampelit.....jpg

После щелчка по ошибке в «списке ошибок» курсор будет перенесен на строчку где предполагается синтаксическая ошибка.

oshibki......jpg

После исправлений всех синтаксических ошибок у нас получилось запустить программу.

ne_pravilno_poschitali.....jpg

При попытке расчёта, с входными данными 2, 4, -6 мы получаем ответ «нет корней». Это неправильный ответ. Придётся искать логические ошибки. В этом нам и поможет «отладчик».

Рассмотри наш проект. И заметим строчки где выполняются вычисления. Это строчки:

  • 1)double d = b * b + 4 * a * c;
  • 2)double x1 = (b + Math.Sqrt(d)) / 2 * a;
  • 3)double x2 = (b - Math.Sqrt(d)) / 2 * a;
  • 4)double x = (-b / 2 * a);

Выделим СЛЕДУЮЩУЮ строчку после этих строчек, и нажмем клавишу F9. Это клавиша для создания «точки остановки компиляции». Если выполнение программы дойдёт до данной точки, то компиляция остановится, и вы уведите значения всех переменных, которые были в момент остановки компиляции. Снять «точку» можно просто выполнив щелчек левой кнопкой мыши.

Начнём процесс компиляции. Когда процесс дойдёт до «точки остановки», мы увидим значения переменных.

Если самому попробовать пересчитать. Мы получим ответ не 32, а ответ 64. Значит мы ищем ошибку в строчке «double d = b * b + 4 * a * c;». Эта сточка должна выглядить так: «double d = b * b - 4 * a * c;»

После изменений. Мы заново запускаем программу. И получаем уже корректное значение переменной d. Затем с помощью кнопки f10, мы выполняем программу дальше, до следующих точек остановки.

Но наша программа по прежнему не корректно работает. Мы аналогичным способом находим еще 2 ошибки.

  • double x1 = (b + Math.Sqrt(d)) / 2 * a; заменяем на double x1 = (-b + Math.Sqrt(d)) / 2 * a;
  • double x2 = (b - Math.Sqrt(d)) / 2 * a; заменяем на double x2 = (-b - Math.Sqrt(d)) / 2 * a;

После исправления всех ошибок, программа выдаёт верный ответ.

Мы «прогоняем» через программу как можно больше тестов. Чтобы рассмотреть все возможные случаи.

ОТЛАДКА ОКОНЧЕНА! ПРОГРАММА РАБОТАЕТ!

Так должен выглядеть отлаженный код:

      {           
          int a, b, c;           
          X11.Visible = false;
          X22.Visible = false;
          XX.Visible = false;
          xx1.Visible = false;
          xx1.Visible = false;
          xx2.Visible = false;
          neet.Visible = false;
          primer.Visible = false;
          a = Convert.ToInt32(aa.Value);
          b = Convert.ToInt32(bb.Value);
          c = Convert.ToInt32(cc.Value);
          double d = b * b - 4 * a * c;
          if (d > 0)
          {
              X11.Visible = true;
              X22.Visible = true;
              double x1 = (-b + Math.Sqrt(d)) / 2 * a;
              double x2 = (-b - Math.Sqrt(d)) / 2 * a;
              xx1.Visible = true;
              xx2.Visible = true;
              xx1.Text = x1.ToString();
              xx2.Text = x2.ToString();
          }
          if (d < 0)
          {
              neet.Visible = true;
              neet.Text = "нет корней";
          }
          if (d == 0)
          {
              XX.Visible = true;
              neet.Visible = true;
              double x = (-b / 2 * a);
              neet.Text = x.ToString();
          }
          primer.Text = a + "X^2+" + b + "X+" + c + "=0";
          primer.Visible = true;
      }

Основные рекомендации написании программы и отладке

bsod.jpg

  1. Обязательно комментировать код. Возможно вам это покажется необязательным, но это всёже ОЧЕНЬ важная вещь. Возможно вы захотите улучшить свою программу через месяц, когда уже забыли как она работает. Или же вы работаете в команде, другой член команды не сможет понять ваш код, испортит его. Комментирование кода очень важно.
  2. Тщательнее тестировать ваш код. Необходимо делать как можно более сложные вычисления, нестандартные.
  3. Максимально упрощать пример. Если у вас не работает программа, которая читае данные, обрабатывает массив, записывает данные в файл, читает их снова, то разбейте программу на составляющие и выполняйте по очереди. Если у вас не работает сложная подпрограмма обрабатывающая данные из файла - напишите сначала тест в две строчки чтобы убедиться, что вы хотя бы можете считытавать введенные данные.
  4. Вывод отладочной информации. Проверяйте значение КАЖДОЙ переменной! Каждого значения, возвращаемого функцией! В файл записывается пустая строка? Проверяйте составляющие этой строки на каждом этапе ее создания и выводите на экран! Убедились, что на экран выводится? Тренируйтесь писать в файл, на тестовой строке! Забитой прямо в код! Уменьшайте количество неизвестных!
  5. Оптимизировать код. Не стоит заставлять компьютер пересчитывать 100 мл. элементов массива.
  6. Обращать внимания на все ошибки. Не стоит не обращать внимания на незначительную на первый взгляд ошибку. В дальнейшем это может привести к плачевным последствиям.
  7. Не волноваться, не торопится.

Заключение

Отладка - главное занятие программиста.

Отладка - единственный и самый мощный способ найти ошибку в программе.

 
tema/otladka_programmy.txt · Последние изменения: 2009/04/21 23:16 От pofigist
 
За исключением случаев, когда указано иное, содержимое этой вики предоставляется на условиях следующей лицензии:CC Attribution-Noncommercial-Share Alike 3.0 Unported
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki