Чтение онлайн

на главную - закладки

Жанры

Linux программирование в примерах
Шрифт:

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

#define
для таких состояний именованные константы. Например:

/* Различные состояния, в которых можно

находиться при поиске конца записи. */

#define NOSTATE 1 /* сканирование еще не началось (все) */

#define INLEADER 2 /* пропуск начальных данных (RS = "") */

#define INDATA 3 /* в теле записи (все) */

#define INTERM 4 /* терминатор сканирования (RS = RS = regexp) */

int state;

...

state = NOSTATE;

...

state = INLEADER;

...

if (state != INTERM) ...

На уровне исходного кода это выглядит замечательно. Но опять-таки, есть проблема, когда вы пытаетесь просмотреть код из GDB:

(gdb) print state

$1 = 2

Здесь вы также вынуждены возвращаться обратно и смотреть в заголовочный файл, чтобы выяснить, что означает 2. Какова же альтернатива?

Рекомендация: Для определения именованных констант используйте вместо макросов перечисления (enum). Использование исходного кода такое же, а значения enum может выводить также и отладчик.

Пример, тоже из

io.c
в
gawk
:

typedef enum scanstate {

 NOSTATE, /* сканирование еще не начато (все) */

 INLEADER, /* пропуск начальных данных (RS = "") */

 INDATA, /* в теле записи (все) */

 INTERM, /* терминатор сканирования (RS = "", RS = regexp) */

} SCANSTATE;

SCANSTATE state;

/* ... остальной код без изменений! ... */

Теперь при просмотре state из GDB мы видим что-то полезное:

(gdb) print state

$1 = NOSTATE

15.4.1.3. При необходимости переставляйте код

Довольно часто условие в

if
или
while
состоит из нескольких проверок, разделенных
&&
или
||
. Если эти проверки являются вызовами функций (или даже не являются ими), невозможно осуществить пошаговое прохождение каждой отдельной части условия. Команды GDB
step
и
next
работают на основе операторов (statements), а не выражений (expressions). (Разнесение их по нескольким строкам все равно не помогает).

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

Вот конкретный пример: функция

do_input
из файла
io.c gawk
:

1 /* do_input --- главный цикл обработки ввода */

2

3 void

4 do_input

5 {

6 IOBUF *iop;

7 extern int exiting;

8 int rval1, rval2, rval3;

9

10 (void)setjmp(filebuf); /* for 'nextfile' */

11

12 while ((iop = nextfile(FALSE)) != NULL) {

13 /*

14 * Здесь было:

15 if (inrec(iop) == 0)

16 while (interpret(expression_value) && inrec(iop) == 0)

17 continue;

18 * Теперь развернуто для простоты отладки.

19 */

20 rvall = inrec(iop);

21 if (rvall == 0) {

22 for (;;) {

23 rval2 = rval3 = -1; /* для отладки */

24 rval2 = interpret(expression_value);

25 if (rval2 != 0)

26 rval3 = inrec(iop);

27 if (rval2 == 0 || rval3 != 0)

28 break;

29 }

30 }

31 if (exiting)

32 break;

33 }

34 }

(Номера строк приведены относительно начала этой процедуры, а не файла.) Эта функция является основой главного цикла обработки

gawk
. Внешний цикл (строки 12 и 33) проходит через файлы данных командной строки. Комментарий в строках 13–19 показывает оригинальный код, который читает из текущего файла каждую запись и обрабатывает ее

Возвращаемое

inrec
значение 0 означает, что все в порядке, тогда как ненулевое возвращаемое значение
interpret
означает, что все в порядке. Когда мы попытались пройти через этот цикл, проверяя процесс чтения записей, возникла необходимость выполнить каждый шаг отдельно.

Строки 20–30 представляют переписанный код, который вызывает каждую функцию отдельно, сохраняя возвращаемые значения в локальных переменных, чтобы их можно было напечатать из отладчика. Обратите внимание, как в строке 23 этим переменным каждый раз присваиваются известные, ошибочные значения: в противном случае они могли бы сохранить свои значения от предыдущих итераций цикла. Строка 27 является тестом завершения, поскольку код изменился, превратившись в бесконечный цикл (сравните строку 22 со строкой 16), тест завершения цикла является противоположным первоначальному.

Поделиться:
Популярные книги

Эволюционер из трущоб. Том 9

Панарин Антон
9. Эволюционер из трущоб
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Эволюционер из трущоб. Том 9

Егерь. Опасная Зона

Скиба Николай
2. Зверолов
Фантастика:
рпг
фэнтези
фантастика: прочее
попаданцы
7.17
рейтинг книги
Егерь. Опасная Зона

Книга гор (сборник)

Лукьяненко Сергей Васильевич
Фантастика:
социально-философская фантастика
героическая фантастика
6.12
рейтинг книги
Книга гор (сборник)

Пламенев. Книга IX

Карелин Сергей Витальевич
9. Пламенев
Фантастика:
аниме
уся
сказочная фантастика
фэнтези
фантастика: прочее
5.00
рейтинг книги
Пламенев. Книга IX

Натюрморт с воронами

Престон Дуглас
4. Пендергаст
Фантастика:
ужасы и мистика
9.37
рейтинг книги
Натюрморт с воронами

Геймер. Тетралогия

Андреева Юлия Игоревна
Фантастика:
альтернативная история
6.80
рейтинг книги
Геймер. Тетралогия

Миллион приключений (сборник)

Булычев Кир
15. Отцы-основатели - Русское пространство. Кир Булычев - Собрание сочинений
Фантастика:
научная фантастика
7.00
рейтинг книги
Миллион приключений (сборник)

Экспансия — II

Семенов Юлиан Семенович
11. Штирлиц
Детективы:
исторические детективы
7.78
рейтинг книги
Экспансия — II

Дело чести

Вебер Дэвид Марк
12. Хонор Харрингтон
Фантастика:
космическая фантастика
7.93
рейтинг книги
Дело чести

Генрик Сенкевич. Собрание сочинений. Том 6-7

Сенкевич Генрик
6. Собрание сочинений в девяти томах
Проза:
историческая проза
5.00
рейтинг книги
Генрик Сенкевич. Собрание сочинений. Том 6-7

12 великих комедий

Шекспир Уильям
Вожди Советского Союза
Проза:
классическая проза
6.25
рейтинг книги
12 великих комедий

Киберпространство

Ливадный Андрей Львович
43. Экспансия: История Галактики
Фантастика:
космическая фантастика
7.69
рейтинг книги
Киберпространство

Гарнизон

Николаев Игорь Игоревич
Фантастика:
боевая фантастика
космическая фантастика
6.40
рейтинг книги
Гарнизон

Серые сутки

Сай Ярослав
4. Медорфенов
Фантастика:
фэнтези
аниме
5.00
рейтинг книги
Серые сутки