1. Отладочная печать ("дедовский метод");
2. Интерактивная отладка.
В первом случае в программе в определённых местах добавляются команды, выводящие на экран (в файл) информацию о том, что происходит в программе, значения переменных и пр.
Во втором случае мы выполняем программу по строчкам. В нужных нам местах программа встаёт на паузу, а мы уже сами смотрим своими глазами, что там происходит.
Когда в институтах обучают программированию -- периодически "забывают" обучить студентов использованию интерактивной отладки -- и очень зря. Это очень нужная вещь. Не знаю, возможно полагают, что тема слишком простая, поэтому студенты освоят её самостоятельно?
Второй метод удобнее, но доступен не всегда. Иногда процессы, которые приходится программировать, должны разворачиваться с нормальной скоростью, то есть постановка на паузу всё рушит. Другой случай, когда интерактивная отладка недоступна -- ошибки в программах, уже работающих у пользователя.
***
Был когда-то такой анекдот:
-- Как отлаживать программу на ассемблере?
-- При помощи долгого и вдумчивого взгляда.
Так вот, сейчас я понимаю, что это не анекдот.
3. Третий метод отладки -- это долгий вдумчивый взгляд на код.
Он не настолько успешен, как первые два. Сложные ошибки им не найти. Когда же приходится им пользоваться? Когда есть проблемы с обоими первыми методами. Я лично встречаюсь с таким при работе с микроконтроллерами. Интерактивная отладка там есть -- и она очень помогает в тех случаях, когда программируемый процесс можно прервать. А вот вместо отладочной печати там есть только "отладочный массив". И разбирать его гораздо сложнее и неудобнее, чем просто посмотреть на свой код и немного подумать.
P.S. Некоторые среды разработки в сочетании с некоторыми типами микроконтроллеров позволяют выводить сообщения через программатор в специальное окно в среде разработки. Поэтому если это можно настроить то, конечно же, так и следует сделать.