Linux программирование в примерах
Шрифт:
1 #include <stdio.h>
2 #include "dbug.h"
3
4 int
5 main(argc, argv)
6 int argc;
7 char *argv[];
8 {
9 register int result, ix;
10 extern int factorial, atoi;
11
12 DBUG_ENTER("main");
13 DBUG_PROCESS(argv[0]);
14 DBUG_PUSH_ENV("DBUG");
15 for (ix = 1; ix < argc && argv[ix][0] == '-'; ix++) {
16 switch (argv[ix][1]) {
17 case '#':
18 DBUG_PUSH(&(argv[ix][2]));
19 break;
20 }
21 }
22 for (; ix < argc; ix++) {
23 DBUG_PRINT("args", ("argv[%d] = %s", ix, argv[ix]));
24 result = factorial(atoi(argv(ixj));
25 printf("%d\n", result);
26 fflush(stdout);
27 }
28 DBUG_RETURN(0);
29 }
Эта программа иллюстрирует большинство важных моментов. Макрос
DBUG_ENTER
(строка 12) должен быть вызван после объявлений переменных и перед любым другим кодом. (Это потому, что он сам объявляет несколько частных переменных. [176] ) Макрос
DBUG_PROCESS
(строка 13) устанавливает имя программы, главным образом, для использования в выводимых библиотекой сообщениях. Этот макрос должен вызываться лишь однажды, из main
.176
В C99, который допускает смешивание объявлений переменных с исполняемым кодом, это составляет меньшую проблему, но помните, что этот пакет был разработан для K&R С — Примеч. автора.
Макрос
DBUG_PUSH_ENV
(строка 14) заставляет библиотеку проверить указанную переменную окружения (в данном случае DBUG
) на предмет управляющей строки (Управляющие строки dbug
вскоре будут рассмотрены.) Библиотека может, сохранив свое текущее состояние и использовав новое, создавать стек сохраненных состояний. Таким образом, этот макрос помещает в стек сохраненных состояний полученное от данной переменной окружения состояние. В данном примере использован случай, когда макрос создает первоначальное состояние. Если такой переменной окружения нет, ничего не происходит. (В качестве отступления, DBUG
является довольно общей переменной, возможно, GAWK_DBUG
было бы лучше [для gawk
].) Макрос
DBUG_PUSH
(строка 18) передает значение управляющей строки, полученной из опции командной строки – #
. (Новый код должен использовать getopt
или getopt_long
вместо ручного анализа аргументов.) Таким образом обычно включается режим отладки, но использование переменной окружения предоставляет также дополнительную гибкость. Макрос
DBUG_PRINT
(строка 23) осуществляет вывод. Второй аргумент использует методику, которую мы описали ранее (см. раздел 15.4.1.1 «Используйте отладочные макросы»), по включению в скобки всего списка аргументов printf
, делая его простым аргументом, насколько это касается препроцессора С. Обратите внимание, что завершающий символ конца строки в форматирующей строке не указывается; библиотека dbug
вставляет его за вас. При печати
dbug
по умолчанию выводит все операторы DBUG_PRINT
. Первый аргумент является строкой, которая может использоваться для ограничения вывода лишь теми макросами DBUG_PRINT
, которые используют эту строку. Наконец, макрос
DBUG_RETURN
(строка 28) используется вместо обычного оператора return
для возврата значения. Для использования с функциями void
имеется соответствующий макрос DBUG_VOID_RETURN
. Оставшаяся часть программы заполнена функцией
factorial
: 1 #include <stdio.h>
2 #include "dbug.h"
3
4 int factorial (value)
5 register int value;
6 {
7 DBUG_ENTER("factorial");
8 DBUG_PRINT("find", ("find %d factorial", value));
9 if (value > 1) {
10 value *= factorial(value — 1);
11 }
12 DBUG_PRINT("result", ("result is %d", value));
13 DBUG_RETURN(value);
14 }
Когда программа откомпилирована и скомпонована вместе с библиотекой
dbug
, ее можно запустить обычным способом. По умолчанию, программа не создает вывод отладки. Но со включенной отладкой доступны различные виды вывода: $ factorial 1 2 3 /* Обычный запуск, без отладки */
1
2
6
$ factorial -#t 1 2 3/* Вывести трассировку вызовов функций, обратите внимание на вложенность */
| >factorial
| <factorial
1 /* Обычный вывод в stdout */
| >factorial
| | >factorial
| | <factorial /* Вывод отладки в stderr */
| <factorial
2
| >factorial
| | >factorial
| | | >factorial
| | | <factorial
| | <factorial
| <factorial
6
<?func?
$ factorial -#d 1 2/* Показать отладочные сообщения DBUG_PRINT */
?func?: args: argv[2] = 1
factorial: find: find 1 factorial
factorial: result: result is 1
Поделиться:
Популярные книги
Личный аптекарь императора. Том 4
4. Личный аптекарь императора
Фантастика:
городское фэнтези
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Последний Паладин. Том 2
2. Путь Паладина
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Неучтенный элемент. Том 8
8. Антимаг. Вне системы
Фантастика:
фэнтези
5.00
рейтинг книги
Черный Маг Императора 20
20. Черный маг императора
Фантастика:
юмористическое фэнтези
аниме
сказочная фантастика
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Л. Пантелеев — Л. Чуковская. Переписка (1929–1987)
Документальная литература:
биографии и мемуары
5.00
рейтинг книги
Ученик. Книга 4
4. Ученик
Фантастика:
фэнтези
5.67
рейтинг книги
Наследие Маозари 9
9. Наследие Маозари
Фантастика:
попаданцы
постапокалипсис
рпг
сказочная фантастика
6.25
рейтинг книги
Кодекс Охотника. Книга XIX
19. Кодекс Охотника
Фантастика:
фэнтези
5.00
рейтинг книги
Тринадцатый IX
9. Видящий смерть
Фантастика:
фэнтези
попаданцы
аниме
сказочная фантастика
5.00
рейтинг книги
Война
7. Ермак
Фантастика:
боевая фантастика
альтернативная история
5.25
рейтинг книги
Последний Паладин
1. Путь Паладина
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Князь Андер Арес 3
3. Андер Арес
Фантастика:
рпг
аниме
фэнтези
5.00
рейтинг книги
Справочник логопеда
Научно-образовательная:
медицина
6.25
рейтинг книги
Сирийский рубеж
5. Рубеж
Фантастика:
попаданцы
альтернативная история
5.00