- Глава 13. Отладка программ
Глава 13. Отладка программ
При разработке программ, особенно в первое время, возможны ошибки как синтаксические, так и логические. Чем сложнее программа, тем труднее их обнаружить. Дня облегчения обнаружения и устранения ошибок в среде разработки Borland C++Builder 6 существует встроенный отладчик программ. Он позволяет выполнять программу по шагам, устанавливать точки останова, просматривать переменные и т. п.
Несмотря на то, что созданные нами программы очень просты, я намеренно хочу рассказать об отладке программ. Дело в том, что рано или поздно в создаваемой программе могут появиться ошибки: или синтаксические, или более сложные для обнаружения логические ошибки. И тогда потребуется инструмент для их устранения. Чем быстрее мы познакомимся с таким инструментом, тем легче нам будет создавать более сложные программы.
После разработки любого приложения необходимо выполнить его компиляцию, компоновку и тестирование. Эти операции выполняются автоматически каждый раз при выполнении команды Run из главного меню среды разработки Borland C++ Builder 6. Однако данные процедуры можно выполнять по отдельности с целью сокращения времени на отладку всего проекта в целом. В нашем очередном примере мы будем пользоваться различными командами трансляции (компиляции и компоновки) проекта. Рассмотрим, в чем состоит отличие между этими командами. Например, компиляцию отдельного модуля программы можно выполнить с помощью команды главного меню Project Compile. При этом не будет затрачено время на компиляцию и компоновку всего проекта в целом. Команда главного меню Project Make позволяет выполнить компиляцию только тех модулей, которые были отредактированы, после чего выполняет компоновку проекта с созданием исполняемого модуля с расширением ехе. Таким образом, эта команда также экономит время на трансляцию проекта в целом. И только команда Project Build компилирует все модули независимо от того, редактировались они или нет. А затем компонует проект и готовит исполняемый файл с расширением ехе. Данная команда необходима для переработки всего проекта после изменения настроек компилятора или среды разработки в целом. Команда Project Run в отличие от Project Build автоматически запускает исполняемый файл.
На этапе компиляции происходит автоматический поиск синтаксических ошибок, неправильного объявления или использования переменных и т. п. При обнаружении подобных ошибок в инспекторе кодов будет выведено соответствующее сообщение об ошибке или предупреждение. Предупреждение в отличие от ошибки не блокирует выполнение программы, но не гарантирует корректность ее работы. Если ошибок в программе нет, компилятор создает объектный (машинный) код программы в модулях (файлах) с расширением obj.
При компоновке программы также выявляются некоторые виды ошибок, связанные с отсутствием объявления переменных, функций, библиотек и т. п., и выполняется объединение всех объектных модулей и библиотек при необходимости в один исполняемый файл с расширением ехе. Вместо исполняемого файла может создаваться библиотечный файл с расширением lib или dll при соответствующих установках среды разработки. Рассмотрим выполнение описанных процедур на конкретном примере. Создадим небольшое приложение на форме Form1 с двумя кнопками Button1, Button2 и одним элементом надписи Label1. О том, как размешаются эти элементы на форме, рассказывалось в главе 7. Это приложение должно сообщать нам о количестве нажатий на первую кнопку. При нажатии на вторую кнопку приложение должно закрываться. Разместите эти элементы на форме Form1 и измените размер формы в соответствии с рис. 13.1.
Рис. 13.1. Внешний вид формы Form1
Теперь замените свойство Caption всех объектов приложения в инспекторе объектов на заголовки Программа 2, Кнопка 1, Выход и пустую строку соответственно. В результате у вас должно получиться окно, показанное на рис. 13.2. Обратите внимание, что элемент Label1, располагающийся выше кнопок, не виден, поскольку мы изменили его свойство Caption на пустую строку, то есть очистили это свойство.
Рис. 13.2. Внешний вид измененной формы Form1
Щелкните дважды левой кнопкой мыши по созданной кнопке Выход и в отрывшемся окне инспектора кодов впишите между фигурными скобками заготовки обработчика события, команду закрытия приложения close ();. Вернитесь к окну формы и щелкните дважды левой кнопкой мыши по кнопке с названием Кнопка 1. В отрывшемся окне инспектора кодов впишите между фигурными скобками следующую строку:
Label1->Caption="Kнonкa 1 нажата " + IntToStr(++i) +" раз";
В этой строке команд выполняется присвоение (знак "равно") свойству Caption, элемента надписи Label1, текстовой строчки, состоящей из трех слагаемых частей. Поскольку свойство Caption элемента надписи Label1 предназначено для отображения текста, мы должны присваивать этому свойству только текстовые (строковые) значения. В языке C++ такие строковые значения заключаются в кавычки. Первая и последняя части присваиваемого значения таковыми и являются. Счетчиком количества нажатий на кнопку в программе будет служить переменная ±, которая должна автоматически увеличиваться на единицу перед выводом. Для этой цели перед ней записаны два знака -. Данная операция в языке C++ называется автоинкрементом. Для превращения числовой переменной i в строковую переменную используется встроенная функция C++ преобразования целых чисел в строки intToStr(). Итак в одной строке команд мы осуществили целый ряд операций. Разве это не изящный язык программирования?!
Сохраните проект под именем butct.bpr, а программный модуль под именем Ubutct.cpp. Впрочем, имена вы можете дать любые другие. Не допускается лишь использование в этих именах русских букв. И не изменяйте расширения файлов.
Теперь попробуем скомпилировать, скомпоновать и выполнить данное приложение, а заодно проверить, нет ли в нем ошибок. Выполните команду Compile из группы Project главного меню или нажмите комбинацию клавиш для компиляции программы <Alt>+<F9>. Перед вами откроется окно, приведенное на рис. 13.3.
Рис. 13.3. Окно компиляции программы
В верхней строке этого окна отображается путь размещения и имя проекта программы. В следующей строке вначале отображается процесс компиляции, сменяющийся записью Done, говорящей о завершении данной операции, и сообщением об обнаруженных ошибках There are errors (Здесь есть ошибки). Ниже отображается номер текущей строки программы Current line и общее количество строк программы Total lines. В нижней строке отображается обнаруженное на данный момент число замечаний Hints, предупреждений Warnings и ошибок Errors. Как видим, в программе есть одна ошибка. Нажмите кнопку ОК — и перед вами окажется окно инспектора кода с выделенной строкой, имеющей ошибку, и сообщением о типе ошибки (рис. 13.4).
Рис. 13.4. Окно инспектора кода
Строка [C++ Error] Ubutct.pp(29): E2451 Undefined symbol 'i' сообщает о том, что компилятор C++ обнаружил ошибку в 29-й строке модуля Ubutct.cpp. Код ошибки Е2451 означает, что обнаружен необъявленный символ. В нашем случае это переменная с именем i. Действительно, мы не объявили ее в программе, хотя и сделали это намеренно, с целью получения сообщения об ошибке в качестве примера. В языке C++, как впрочем и в других языках программирования, все переменные, используемые в программе, необходимо объявлять. Это делается для того, чтобы компилятор знал, сколько ячеек памяти необходимо резервировать в памяти компьютера для ее хранения. Поскольку различные типы переменных требуют для своего хранения различное количество ячеек памяти (байт), рационально резервировать для них лишь необходимый объем памяти. В нашем случае переменная i является целой, то есть принимающей только целочисленные значения. Для ее объявления необходимо использовать директиву int (от integer, целый). Можно сделать такое объявление непосредственно в тексте программы обработчика событий, но тогда эта переменная будет недоступна в других функциях обработчика. Поэтому мы объявим ее в блоке public файла описания заголовков Ubutct.h. Для этого необходимо щелкнуть левой кнопкой мыши по вкладке Ubutct.h инспектора кодов и вписать строку объявления переменной с комментариями сразу же после строчки public. Ниже, в листинге 12.1, эта запись приведена полностью.
Листинг 12.1. Строки объявления переменной i
int i; // Переменная - счетчик
Теперь снова выполним компиляцию и обнаружим, что ошибок нет. Но не спешите радоваться. Дело в том, что мы не присвоили переменной i начального значения. Компилятор не обращает на это внимания и не выдает никаких сообщений по этому поводу. Но в программе это может привести к недоразумениям. Поэтому выполним присвоение начального значения переменой i, сделав запись i=0; (ведь при запуске программы Кнопка 1 не была нажата ни разу) в тексте программы обработчика создания формы. Для этого щелкните дважды левой кнопкой мыши по форме приложения и в открывшемся окне инспектора кода впишите между фигурными скобками текста программы строку i=0;.
Выполним компоновку проекта с помощью команды Make из группы Project главного меню или нажав комбинацию клавиш для компоновки программы <Ctrl>+<F9>. В результате мы должны получить безошибочную компоновку приложения. Теперь приложение можно сохранить и запустить на выполнение с помощью команды Run или воспользоваться горячей кнопкой запуска программы <F9>.
На экране появится окно нашей программы. Щелкая левой кнопкой мыши по кнопке с названием Кнопка 1, вы увидите, что каждый раз в окне будет появляться сообщение о количестве нажатий этой кнопки.
- Каждый раз перед запуском приложения после редактирования обязательно сохраняйте проект. Это позволит избежать потери информации при зависании программы, вызванном наличием в ней ошибок.