Нейл Мэтью - Основы программирования в Linux
- Название:Основы программирования в Linux
- Автор:
- Жанр:
- Издательство:«БХВ-Петербург»
- Год:2009
- Город:Санкт-Петербург
- ISBN:978-5-9775-0289-4
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Нейл Мэтью - Основы программирования в Linux краткое содержание
В четвертом издании популярного руководства даны основы программирования в операционной системе Linux. Рассмотрены: использование библиотек C/C++ и стандартных средств разработки, организация системных вызовов, файловый ввод/вывод, взаимодействие процессов, программирование средствами командной оболочки, создание графических пользовательских интерфейсов с помощью инструментальных средств GTK+ или Qt, применение сокетов и др. Описана компиляция программ, их компоновка c библиотеками и работа с терминальным вводом/выводом. Даны приемы написания приложений в средах GNOME® и KDE®, хранения данных с использованием СУБД MySQL® и отладки программ. Книга хорошо структурирована, что делает обучение легким и быстрым.
Для начинающих Linux-программистов
Основы программирования в Linux - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Если мы внесем эту поправку, назвав результат debug3.c, то получим ошибку сегментации в версиях Linux обоих авторов.
/* 2 */ char data[4096];
$ сс -о debug3 debug3.с
$ ./debug3
Segmentation fault
Возможно, что какие-то варианты систем Linux или UNIX все еще не будут выдавать сообщение об ошибке сегментации. Когда стандарт ANSI С утверждает, что поведение не определено, на самом деле он разрешает программе делать все, что угодно. Это выглядит так, как будто мы написали не удовлетворяющую стандартам программу на языке С, и она может демонстрировать очень странное поведение! Как видите, изъян в программе переводит ее в категорию программ с непредсказуемым поведением.
Анализ кода
Как мы упоминали ранее, часто, если программа не работает, как ожидалось, неплохо перечитать ее. Предположим, что мы просмотрели программный код примера этой главы и исправили в нем все очевидные ошибки.
Анализ кода — это термин, применяемый для обозначения более формального процесса, в ходе которого группа разработчиков тщательно просматривает несколько сотен строк программного кода, но масштаб не имеет значения, это все равно анализ кода, и он остается очень полезным методом поиска ошибок.
Существуют средства, которые могут помочь в анализе кода, одно из самых очевидных — компилятор. Он сообщит вам о любых имеющихся в вашей программе синтаксических ошибках.
У некоторых компиляторов есть опции, формирующие предупреждения в сомнительных случаях, таких как отсутствие инициализации переменных или применение присваиваний в условиях. Например, компилятор GNU можно запускать со следующими опциями:
gcc -Wall -pedantic -ansi
Они порождают много предупреждений и дополнительных проверок на соответствие стандартам языка С. Рекомендуем взять за правило использование этих опций, особенно Wall
. Она генерирует полезную информацию при обнаружении ошибок в программе.
Чуть позже мы кратко обсудим и другие средства, lint
и splint
. Как и компилятор, они анализируют код и сообщают о фрагментах кода, которые могут быть некорректными.
Оснащение средствами контроля
Оснащение средствами контроля — это вставка в программу кода для сбора дополнительной информации о поведении программы во время ее выполнения. Очень популярна вставка вызовов функции printf
для вывода значений переменных на разных стадиях выполнения программы. Вы можете с пользой для себя добавить несколько вызовов printf
, но должны знать о том, что этот процесс повлечет за собой дополнительные редактирование и компиляцию при любом изменении программы и, конечно, вам придется удалить код, когда ошибки будут исправлены.
Здесь могут помочь два метода оснащения средствами контроля. Первый использует препроцессор языка С для выборочного включения кода средств контроля так, что вам нужно только перекомпилировать программу для вставки или удаления отладочного кода. Сделать это можно очень просто, с помощью конструкций, подобных приведенным далее:
#ifdef DEBUG
printf("variable x has value = %d\n", x);
#endif
Вы можете компилировать программу с флагом компилятора -DDEBUG
для определения символического имени DEBUG
и включения дополнительного кода и без этого флага — для удаления отладочного кода. Можно создать и более сложный вариант использования пронумерованных отладочных макросов:
#define BASIC_DEBUG 1
#define EXTRA_DEBUG 2
#define SUPER_DEBUG 4
#if (DEBUG & EXTRA_DEBUG)
printf...
#endif
В этом случае вы всегда должны определять макрос DEBUG
, но можете настраивать объем отладочной информации или уровень детализации. Флаг компилятора -DDEBUG=5
в нашем примере активизирует макросы BASIC_DEBUG
и SUPER_DEBUG
, но не EXTRA_DEBUG
. Флаг DDEBUG=0
отключит всю отладочную информацию. С другой стороны, вставка следующих строк устранит необходимость задания в командной строке DEBUG
, если отладки не требуется.
#ifndef DEBUG
#define DEBUG 0
#endif
Несколько макросов, определенных препроцессором С, могут предоставить отладочную информацию. Эти макросы раскрываются для предоставления сведений о текущей компиляции (табл. 10.1).
Обратите внимание на то, что приведенные символические имена начинаются и заканчиваются двумя символами подчеркивания. Это стандартное правило для символических имен препроцессора, и вы должны аккуратно выбирать идентификаторы, чтобы избежать конфликтов. Термин "текущие" в предыдущих описаниях указывает на момент выполнения препроцессорной обработки, т.е. время и дата запуска компилятора и обработки файла.
Таблица 10.1
Макрос | Описание |
---|---|
__LINE__ |
Десятичная константа, предоставляющая номер текущей строки |
__FILE__ |
Строка, предоставляющая имя текущего файла |
__DATE__ |
Строка в форме "ммм дд гггг", текущая дата |
__TIME__ |
Строка в форме "чч:мм:сс", текущее время |
Выполните упражнение 10.1.
Далее приведена программа cinfo.c, которая выводит дату и время компиляции, если включен режим отладки.
#include
# include
int main() {
#ifdef DEBUG
printf("Compiled: " __DATE__ " at " __TIME__ "\n");
printf("This is line %d of file %s\n", __LINE__, __FILE__);
#endif
printf("hello world\n");
exit(0);
}
Когда вы откомпилируете эту программу с включенным режимом отладки (используя флаг -DDEBUG
), то увидите следующие сведения о компиляции:
$ cc -о cinfo -DDEBUG cinfo.c
$ ./cinfo
Compiled: Jun 30 2007 at 22:58:43
This is line 8 of file cinfo.c
hello world
$
Как это работает
Препроцессор С, часть компилятора, отслеживает текущую строку и текущий файл во время компиляции. Он подставляет текущие (времени компиляции) значения этих переменных везде, где обнаруживает символические имена __LINE__
и __FILE__
. Дата и время компиляции становятся доступными аналогичным образом.
Поскольку __DATE__
и __TIME__
— строки, вы можете объединить их в функции printf
с помощью строк формата, т.к. в языке С ANSI смежные строки воспринимаются как одна.
Прежде чем двигаться дальше, стоит отметить, что существует способ применения функции printf
, позволяющий отлаживать программу без применения метода #ifdef DEBUG
, требующего перекомпиляции программы перед ее использованием.
Метод заключается во вставке глобальной переменной как флага отладки, разрешении опции -d
в командной строке, которая дает возможность пользователю включить отладку даже после того, как программа была введена в эксплуатацию, и включении функции мониторинга процесса отладки. Теперь можно вкраплять в код программы строки, подобные следующим:
Интервал:
Закладка: