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

на главную

Жанры

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), тест завершения цикла является противоположным первоначальному.

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

На границе империй. Том 3

INDIGO
3. Фортуна дама переменчивая
Фантастика:
космическая фантастика
5.63
рейтинг книги
На границе империй. Том 3

Держать удар

Иванов Дмитрий
11. Девяностые
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Держать удар

Эффект Фостера

Аллен Селина
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Эффект Фостера

Не грози Дубровскому! Том VIII

Панарин Антон
8. РОС: Не грози Дубровскому!
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Не грози Дубровскому! Том VIII

СД. Том 17

Клеванский Кирилл Сергеевич
17. Сердце дракона
Фантастика:
боевая фантастика
6.70
рейтинг книги
СД. Том 17

Темный Патриарх Светлого Рода 3

Лисицин Евгений
3. Темный Патриарх Светлого Рода
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Темный Патриарх Светлого Рода 3

Сумеречный Стрелок 3

Карелин Сергей Витальевич
3. Сумеречный стрелок
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Сумеречный Стрелок 3

Пипец Котенку!

Майерс Александр
1. РОС: Пипец Котенку!
Фантастика:
фэнтези
юмористическое фэнтези
аниме
5.00
рейтинг книги
Пипец Котенку!

Неудержимый. Книга IV

Боярский Андрей
4. Неудержимый
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Неудержимый. Книга IV

Дурная жена неверного дракона

Ганова Алиса
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Дурная жена неверного дракона

Я не князь. Книга XIII

Дрейк Сириус
13. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я не князь. Книга XIII

Я – Орк. Том 6

Лисицин Евгений
6. Я — Орк
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я – Орк. Том 6

Отмороженный

Гарцевич Евгений Александрович
1. Отмороженный
Фантастика:
боевая фантастика
рпг
5.00
рейтинг книги
Отмороженный

Безродный

Коган Мстислав Константинович
1. Игра не для слабых
Фантастика:
боевая фантастика
альтернативная история
6.67
рейтинг книги
Безродный