
- •Список сокращений
- •Введение
- •Маршрут разработки программ
- •Компилятор gnu gcc Toolchain
- •Компиляция одного файла
- •Компиляция нескольких файлов
- •Автоматизация сборки
- •Отладка программы
- •Принципы взаимодействия программ и ос
- •Системные вызовы
- •Библиотечные вызовы
- •Запуск и завершение процесса
- •Работа со строками
- •Системные вызовы для работы с файлами и потоками
- •Работа с файлами
- •Работа с потоками ввода-вывода
- •Библиотечные вызовы для работы с файлами и потоками
- •Работа с файлами
- •Работа с потоками ввода-вывода
- •Работа с директориями
- •Упражнения
- •Индивидуальные задания
- •Контрольные вопросы
- •Список литературы
Библиотечные вызовы
Библиотечные вызовы – это стандартизированные функции языка C, которые при необходимости самостоятельно обращаются к системным вызовам. В библиотечных вызовах, как правило, реализованы наиболее часто встречающиеся участки кода, что повышает удобство разработки.
ОС Linux по умолчанию использует библиотеку «glibc» (GNU C Library) для реализации библиотечных вызовов, однако она может быть заменена при необходимости.
Чтобы использовать библиотечные вызовы необходимо подключение соответствующих заголовочных файлов «.h». Обращение к библиотечным вызовам отвязывает программу от конкретной ОС, что делает ее более кроссплатформенной. Но при этом несколько снижается скорость работы программы и возможны потенциально опасные ситуации, связанные с параллельным исполнением программ в ОС Linux.
Запуск и завершение процесса
При вызове программы в командной оболочке, например, с помощью команды
|
./prg arg0 arg1 … argN |
|
в программу передаются аргументы «arg0», «arg1» и т. д. Для того, чтобы внутри кода вызываемой программы можно было корректно оперировать переданными аргументами, ее функция «main» должна иметь вид, представленный в Листинге Листинг 3:
Листинг 3. Пример функции main
-
1.
2.
3.
4.
5.
int main (int argc, char *argv[]) {
int ret;
// код программы
return ret;
}
где «int argc» – общее количество передаваемых аргументов, а «char *argv[]» – указатель на массив строк, где каждая строка содержит один из аргументов по порядку их написания («arg0», «arg1», …, «argN»). При этом значение argv[0] всегда представляет собой имя программы. Например, при вызове:
|
./prg abc 123 -f |
значение переменной «argc» будет равно 3, а значения в массиве «argv»:
argv[0] = “./prg”
argv[1] = “abc”
argv[2] = “123”
argv[3] = “-f”
Каждая функция «main» должна иметь тип возвращаемого значения «int». Оно является кодом, свидетельствующим об успешности или не успешности завершения программы. Самостоятельное завершение программы возможно несколькими способами: попадание в «return» функции «main» или применение библиотечного вызова «exit» (или аналогичных системных вызовов) в произвольной части программы:
#include <stdlib.h>
void exit(int status);
где входной аргумент «int status» представляет собой возвращаемое программой значение.
По умолчанию, для большинства программ «0» в возвращаемом значении соответствует успешности выполнения, а его отрицательные значения принято воспринимать как код ошибки. Многие системные и библиотечные вызовы возвращают «-1», а конкретный код, по которому можно идентифицировать возникшую ошибку, записывают в глобальную переменную «errno». Для ее использования необходимо подключить соответствующий заголовочный файл:
#include <errno.h>
При завершении вызванной программы в командной оболочке возвращаемое ей значение автоматически сохраняется в переменную «?» (знак вопроса).