ba8f354f6c147e649bdb042286b1e414.ppt
- Количество слайдов: 82
C SELECTED TOPICS. COURSE OF LECTURES
LECTURE #1
Введение Язык Си был разработан в начале 1970 х годов для упрощения переноса операционной системы UNIX на разные архитектуры. За прошедшие почти 40 лет было опубликовано несколько стандартов языка. Наиболее значимые из них: ●K&R C - первое описание языка Си от авторов языка: Кернигана и Ритчи. ●ANSI C - стандарт американского института стандартов ●C 99 - стандарт ISO/IEC 9899: 1999
Компиляция Большинство реализаций языка Си - компиляторы. Компиляция программ происходит в три стадии: обработка препроцессором ●компиляция в объектный код ●компоновка (сборка) всех модулей в выполняемый файл или разделяемую библиотеку ●
Препроцессор выполняет предварительную обработку текста программы. В его функции входит: ●замена констант на значения и разворачивание макросов ●обработка директив условной компиляции ●включение в текст внешних файлов После обработки получается текст, который может быть скомпилирован в объектный файл без использования каких либо внешних файлов. Посмотреть результат обработки препроцессором можно, например, командой gcc -E main. c -o main. out. c (Файл main. out. c будет содержать результат работы препроцессора)
Компиляция В процессе компиляции файл на языке Си преобразуется в объектный файл, содержащий машинный код, таблицу содержащихся в файле символов и таблицу необходимых этому файлу внешних символов.
Компоновка В процессе компоновки один или несколько объектных файлов преобразуются в выполняемый образ. На этом этапе происходит разрешение ссылок на внешние символы.
В Си допустимыми символами являются латинские заглавные и строчные буквы, цифры и следующие знаки препинания: ● % процент ● Алфавит языка ^ амперсанд ● ! восклицательный знак ● ( ) { } [ ] круглые, фигурные и квадратные скобки ● . точка , запятая ● ; точка с запятой ● ^ крышка ● | вертикальная прямая ● ? вопросительный знак ● : двоеточие ● ● ● ~ тильда + плюс ● ' %%"%% одинарные и двойные кавычки ● ● - минус ● * умножение ● / прямая и обратная дробь ● = равно # решетка ● _ подчеркивание Пробельными символами считаются: пробел, табуляция, перевод строки. Такие символы игнорируются компилятором.
Комментарии Коментарий начинается с /* и заканчивается */. В Си нет вложенных коментариев.
Служебные слова Следующие слова являются ключевыми и не рекомендуется использовать их для обозначения имен функций и переменных. ● extern ● register ● static ● break ● char ● short ● case ● int ● continue ● long ● default ● float ● double ● else enum ● ● for struct ● goto ● ● if ● return ● switch ● while ● sizeof ● typedef ● ● ● union signed unsigned void volatile
Идентификаторы Идентификатором может считаться любая последовательность символов состоящая из латинских букв, цифр, подчеркивания, при условии, что она начинается с латинской буквы. Регистр букв имеет значение, т. е. идентификаторы A 1 и a 1 обозначают разные сущности.
Простые типы ●void - "пустой" тип (используется как возвращаемый тип в создания указателей на нетипизированную память) ●char - целое число размерностью 1 байт ●int - целое число процедурах и для С типом int могут употребляться модификаторы sort и long, например: ●short int (или просто short) - целое число меньшей размерности, чем int ●long int (или просто long) - целое число большей размерности, чем int Со всеми вышепреведенными типами кроме void могут употребляться модификаторы signed и unsigned, например: ●signed short int (или просто short) ●unsigned int ●unsigned long int (или просто unsigned long) ●unsigned char
Константы Целочисленные константы представляются в виде: ● 123 - десятичное число 123 ● 077 - восьмеричное число 77 (начинаются с 0) ● 0 x. FF - шестнадцатиричное число FF (начинаются с 0 x) ● 123 L - буква L обозначает приведение к типу long ● 123 U - буква U обозначает беззнаковый тип Вещественные: ● 1. 23 e-5 ● 1. 23 e 3 f Буква f в конце означает тип float (по умолчанию вещественные константы имеют тип double)
Строки: ●"Hello, Worldn" ●"x 20" Символы: ●'c' ●'t' ●'\' В строковых и символьных константах обратная косая имеет особое значение - с ее помощью вставляются управляющие символы. ●n - перевод строки ●t - табуляция ●r - возврат каретки ●x<число> - символ с указанным шестнадцатиричным кодом ● <число> - символ с указанным восьмеричным кодом ●\ обратная дробь
Описание переменных Синтаксис: тип идентификатор [ = выражение][, идентификатор [ = выражение]]. . . ; int a = 1; int a = 1, b, c = 2; Модификаторы: ●const - неизменяемая переменная ●register - помещать переменную в регистр процессора (игнорируется всеми современными компиляторами) ●volatile - может изменяться внешними процессами () ●static - статическая переменная ●auto - локальная переменная (обычно не используется, т. к. все переменные без модификаторов относятся к группе auto)
Приоритеты и ассоциативность операций ●() [] ->. (скобки, индекс массива, получение поля из структуры и получение поля из структуры с разыменованием указателя) ●Унарные (справа налево): ! ~* & sizeof (type) ++ -- (Логическое и битовое отрицание, смена знака, разыменование, взятие указателя, размер, инкремент и декремент) ●Бинарные арифметические: * / % (умножение, деление, остаток) ●Бинарные арифметические + - (сложение и вычитание) ●Сдвиг: << >> (побитовый сдвиг) ●Сравнение: < <= > >= ●Сравнение: == != ●Битовая: & (и) ●Битовая: ^ (исключающее или) ●Битовая: | (или) ●Логическая: && (и) ●Логическая: || (или) ●Тернарная (справа налево): ? : (условие ? выражение 1 : выражение 2) ●Операции с присваиванием (справа налево): = += -= *= /= &= |= ^= <<= >>=
Операторы в Си разделяются символом точка с запятой. Для объединения операторов в блок используются фигурные скобки.
Присваивание Синтаксис: левое значение = правое значение a = 2; b = (a + 2)*3;
Приведение типа Для преобразования типа можно использовать его имя в круглых скобках перед выражением: double x = 1. 3; int a = (int)(x+0. 5); /* правильное округление положительного вещественного */
Операция “запятая” Через запятую можно указать несколько выражений. Результатом операции запятая всегда будет значение правого выражения. int a = 1, 2; /* a == 2 */
if Условный оператор имеет две формы: if (условие) оператор1 else оператор2 if(1 < 2) { // операторы } else { // операторы }
while и do-while Циклы "пока" с пред и постусловием. while(условие) оператор do оператор while(условие)
for Цикл "для" for(действие до цикла; условие выполнения цикла; действие в конце каждой итерации) оператор for(i = 0; i < 10; i = i + 1) printf("%d", i);
goto Оператор перехода к метке. Синтаксис: label 1: . . goto label 1;
switch Оператор выбора позволяет выполнять различные операторы в зависимости от значения выражения. Синтаксис: switch(выражение) { case значение 1: case значение 2: операторы break; case значение 3: операторы break; default: операторы break; }
break, continue Оператор break прекращает выполнение цикла или оператора выбора. Оператор continue вызывает досрочное завершение итерации.
Описание функций Синтаксис: тип идентификатор(список параметров) блок операторов Если в качестве последнего параметра указано троеточие, функция может принимать произвольное количество параметров. При этом у функции должен быть хотя бы один обязательный параметр. int add(int a, int b) { return a + b; } int print(char *format, . . . ) { /*. . . */ }
Программа на языке Си должна содержать как минимум 1 функцию с именем main. int main(int argc, char *argv[]) { return 0; } Выполнение программы начинается именно с этой функции. В качестве параметров она принимает массив аргуметнов, переданных в командной строке и возвращает целое значение, содержащее код ошибки (0 означает, что ошибки нет) int main(int argc, char *argv[]) { if(argc < 4) { /* слишком мало аргументов */ return 1; } /*. . . */ return 0; }
LECTURE #2
Массивы Синтаксис: тип имя-переменной[размер массива] ●тип имя-переменной[] ●тип *имя-переменной ● Индексы массива всегда начинаются с 0. Например: int a[10]; /* массив из 10 элементов от 0 до 9 */ a[5] = 3; /* присвоить 6 му (с индексом 5) элементу значение 3 */
Важно запомнить, что: ●язык Си обычно не предоставляет средств контроля выхода индекса за пределы массива. ●использование имени массива без операции взятия его элемента означает использование указателя на 1 й элемент массива.
Составные типы Структура: struct [имя-структуры] { список полей } Например: struct list_item { int value; struct list_item *next; };
Объединение: union [имя] { список полей } Перечисление: enum [имя] { список значений }
Например: struct multivalue { enum { VALUE_INT, VALUE_CHAR, VALUE_DOUBLE } type; union { int ival; char cval; double dval; } value; };
Определение типа при помощи typedef: typedef <описание типа> <имя типа> Например: typedef struct list_item { int value; struct list_item *next; } list_item_t; После такого описания типа можно вводить переменные двумя способами: ●struct list_item *var 1; ●list_item_t *var 2;
LECTURE #3
Указатели Операция взятия указателя: &<выражение> Операция разыменования указателя: *<выражение> Тип-указатель: тип* Например: int a = 5; int *ptr_to_a = &a; *ptr_to_a = 1; printf("%dn", a); /* напечатает 1 */
Адрессная арифметика С указателями допустимы операции сложения с целым и вычитания одного указателя из другого: Например: int a[10]; int *ptr = &a[0]; *(ptr+1) = 3; /* поместить 3 во 2 й элемент массива */ int diff = &a[5] - ptr; /* 5 элементов разницы */
Важно запомнить, что: ●операции сложения и вычитания учитывают размер типа, на который ссылается указатель. Например, ptr+1 в предыдущем примере увеличивает ptr на размер типа int (обычно 4 байта) ●эти операции не применимы к типу void*, т. к. невозможно узнать размер значения, на которое он ссылается.
массивы указателей и указатель на массив char *array_of_ptrs[]; /* массив указателей на char */ char (*ptr_to_array)[]; /* указатель на массив char */ Указатель на функцию: тип (*имя)(параметры) Например: char* (*ptr_to_func)(char, int); /* описывает указатель на функцию с 2 мя параметрами типа char и int и возвращающую значение типа char* */
Препроцессор занимается предварительной обработкой текста до компиляции. Препроцессор не привязан к языку Си и обрабатывать им можно любые тексты. Он позволяет определять константы, вставлять в текст другие файлы, удалять текст в зависимости от различных условий.
Подключение файлов Синтаксис: #include <файл> #include "файл" Если файл указан в угловых скобках, он ищется в директориях системы/компилятора. Иначе в текущей директории.
LECTURE #4
Константы Синтаксис: #define ИМЯ ЗНАЧЕНИЕ #define ИМЯ(параметры) ЗНАЧЕНИЕ Например, #define DEBUG #define PI 3. 14159 #define ADD(A, B) ((A)+(B)) #define PRINT(A) printf(A) #define FIELD(B, A) ((B)->m_## A) #ifdef DEBUG float a = PI; float b = ADD(a, 5); PRINT(("%fn", b));
Обратите внимание на двойные скобки в PRINT(("%fn", b)) для передачи списка параметров и на операцию ## в определении FIELD, которая соединяет строки. Например использование FIELD(m, next) будет раскрыто препроцессором как ((m)->m_next).
Условная компиляция Синтаксис: #ifdef ИМЯ текст-1 #endif #ifdef ИМЯ текст-1 #else текст-2 #endif Оставляет текст-1 если константа ИМЯ определена при помощи #define и текст-2 в противном случае.
Организация модулей Компиляция программы на Си происходит в три этапа: - обработка текста препроцессором - компиляция каждого файла с исходным текстом - сборка скомпилированных файлов в один (компоновка) Препроцессор позволяет не усложнять язык Си средствами работы с модулями и их подключением. Обычно реализация модуля находится в файле с расширением. c, а прототипы, константы, описания типов, которые могут потребоваться для других модулей - в файлах с расширением. h. Таким образом, если модуль А использует функции модуля Б, то достаточно подключить файл Б. h при помощи директивы #include и после обработки получится файл, пригодный для компиляции, т. к. содержимое Б. h c прототипом функций будет подставлено вместо #include. Обычно определения модуля А. с выносятся в одноимённый hфайл, однако ничто не запрещает объединить определения модулей a. c и b. c в файл my-headers. h или разделить описания модуля a. c на файлы a 1. h и a 2. h.
LECTURE #5
Основные функции ввода-вывода scanf int scanf(const char *format, . . . ) Выполняет чтение данных со стандартного потока ввода (по умолчанию клавиатура). int sscanf(const char *buffer, const char *format, . . . ) Выполняет чтение данных из переменной buffer. int fscanf(FILE *stream, const char *format, . . . ) Выполняет чтение данных из файла stream. Возвращает количество прочитанных элементов.
Параметр format - строка по которой функция будет интерпретировать остальные аргументы. ● Модификаторы ● h - short (для форматов d, i, o, u, x, X, n) ● hh - char ● j - intmax_t ● l - long для форматов d, i, o, u, x, X, n; double для e, f, g; wchar_t для c и s ● L - long для форматов d, i, o, u, x, X, n; long double для e, f, g; wchar_t для c и s ● q - эквивалент L ● t - ptrdiff_t (для форматов d, i, o, u, x, X, n) ● z - size_t (для форматов d, i, o, u, x, X, n) ●
* Формат параметра *%-% * d - int * D - эквивалент ld * i - int (возможно в восьмеричной форме 0. . . или шестнадцатиричной 0 x. . . ) * o - восьмеричный unsigned int * u - unsigned int * x - шестнадцатиричный unsigned int * X - шестнадцатиричный unsigned int с большими буквами A-F * f - float * e - эквивалент f * g - эквивалент f * E - эквивалент f * a - эквивалент f * s - строка непробельных символов * c - char * [ - произвольное число перечисленных символов, например: %[^]0 -9 -] - все кроме ] цифр и -. * p - void* * n - int (количество разобраных символов)
printf int printf(const char *format, . . . ) Печатает форматированные аргументы на стандартный вывод (консоль). int snprintf(char *buffer, size_t bufsize, const char *format, . . . ) Заполняет форматированными аргументами buffer размером bufsize. int fprintf(FILE *stream, const char *format, . . . ) Выводит форматированные аргументы в файл stream. Возвращает количество напечатанных символов.
* Флаги * # - альтернативная форма * для формата o - добавляет 0 вначало * для x и X - добавляет 0 x и 0 X вначало * a, A, f, F, e, E, g, G - всегда печатать точку * g, G - оставить ненужные нули * 0 - заполнять 0 до нужной длины * - - выравнивать по левому краю * + - всегда указывать знак числа * пробел - ставить пробел вместо знака + для положительных чисел * Ширина поля - количество символов для поля * Точность - после точки для вещественных чисел можно указать сколько символов из ширины поля выделить для вещественной части
* Размер * h - char * hh - short * l - long или wchar_t * ll - long * L - long double * j - intmax_t * z - size_t * t - ptrdiff_t
* Тип * d, i - int * o, u, x, X - unsigned int (напечатает в восьмеричной, десятичной или шестнадцатиричной форме) * e, E - вещественное число в нормальной записи * f, F - вещественное число в обычной записи * g, G - вещественное число в автоформате * a, A - вещественное в шестандцатиричном виде * c - char * s - заканчивающаяся нулевым символом строка char или wchar_t * p - void* * n - количество напечатанных символов (не требует соответствующего параметра после строки формата) * m - системное сообщение об ошибке (не требует соответствующего параметра после строки формата) *%-%
Например: #include
Файлы Перед тем как выполнять чтение или запись файла, необходимо его открыть, а по окончании работы закрыть. Существует специальный тип переменных - файловые переменные. Операция открытия файла возвращает переменную данного типа, по которой операции чтения записи идентифицируют файл. - Открытие файла: нужно указать имя файла и режим в котором его нужно открыть (для чтения, для записи, как текст или как двоичные данные). Возвращает файловую переменную. - Операции чтения/записи: нужно указать файловую переменную, полученную при открытии и данные для записи или переменную, в которую необходимо прочитать данные - Закрытие файла: нужно передать файловую переменную.
fopen FILE *fopen(const char *path, const char *mode) Открывает файл path в режиме mode. Режим представлен как строка символов. Допустимы комбинации следующих значений: * r - для чтения * r+ - для чтения и записи. Указатель установлен в начало файла. * w - для записи. Очищает файл. * w+ - для чтения и записи. Очищает файл. * a - добавить в конец файла (для записи). Указатель установлен в конец файла. * a+ - для чтения и записи. Указатель чтения установлен в начало файла, записи - в конец. * b - открыть файл как двоичный, а не текстовой. Возвращает файловую переменную или NULL в случае ошибки.
fclose int fclose(FILE *fp) Закрыть файл. fprintf int fprintf(FILE *stream, const char *format, . . . ) Записать форматированные в текст данные в файл stream. (работает аналогично printf) fscanf int fscanf(FILE *stream, const char *format, . . . ) Читает данные из текстового файла stream. (работает аналогично scanf)
fwrite size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) Записать двоичные данные в файл. * ptr - указатель на переменную, которую нужно записать * size - размер элемента * nmemb - количество элементов (1 - если не массив или кол-во элементов в массиве) * stream - файловая переменная Возвращает количество записанных элементов. Например: int a = 1, b[2] = { 2, 3 }; r = fwrite(&a, sizeof(a), 1, f); /* вернет 1 в случае успешной записи */ r = fwrite(b, sizeof(int), 2, f); /* вернет 2 в случае успешной записи */
fread size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream) Читать двоичные данные из файла. * ptr - указатель на переменную, в которую нужно поместить прочитанные данные * size - размер элемента * nmemb - количество элементов (1 - если не массив или кол-во элементов в массиве) * stream - файловая переменная Возвращает количество прочитанных элементов Например: /*. . . */ int a, b[2]; r = fread(&a, sizeof(a), 1, f); /* вернет 1 в случае успешного прочтения */ r = fread(b, sizeof(int), 2, f); /* вернет 2 в случае успешного прочтения */
feof int feof(FILE *stream) Проверить конец файла. Возвращает 0 если файл stream еще не закончился.
Пример #include
/* * Чтение текста */ txtfile = fopen("test. txt", "r"); if(txtfile != NULL) { int a; fscanf(txtfile, "%d", &a); printf("a(txtfile) = %dn", a); fclose(txtfile); } else { perror("Не могу открыть файл test. txt для чтения"); } /* * Чтение двоичных данных */ binfile = fopen("test. dat", "rb"); if(binfile != NULL) { int a; fread(&a, sizeof(a), 1, binfile); printf("a(binfile) = %dn", a); fclose(binfile); } else { perror("Не могу открыть файл test. dat для чтения"); } return 0; }
LECTURE #6
Функции с переменным числом аргументов При помощи. . . можно определить функцию с переменным числом аргументов. Троеточие всегда должно находиться в конце списка параметров. Например: int func(int count, . . . ); Для обработки переменного числа параметров существуют следующие средства: - тип va_list хранит информацию о состоянии извлечения аргументов функции из стека - функция va_start(va_list, последний именованный параметр) инициализирует процесс извлечения аргументов из стека, принимая первым аргументом переменную типа va_list, а вторым - последний именованный параметр. - макрос va_arg(va_list, тип) возвращает очередной параметр. Второй параметр - определение типа ожидаемого аргумента. - va_end(ap) завершает выборку аргументов из стека
* Параметр stub не используется, но необходим, т. к. для обработки переменного * числа параметров нужно отталкиваться от именованного параметра с известным * типом. (этот параметр не должен быть массивом, функциональным типом или * регистровым параметром) */ int print_strings(char stub, . . . ) { int count = 0; va_list ap; va_start(ap, stub); while(1) { char *s = va_arg(ap, char*); if(s == NULL) { break; } printf("%sn", s); count++; } va_end(ap); return count;
Строковые функции * char *strcpy(char *dest, const char *src); - копирование строки * char *strncpy(char *dest, const char *src, size_t n); - копирование строки с указанием максимального размера * char *strcat(char *dest, const char *src); - соединение строк * char *strncat(char *dest, const char *src, size_t n); - соединение строк с указанием максимального размера * int strcmp(const char *s 1, const char *s 2); - сравнение строк * int strncmp(const char *s 1, const char *s 2, size_t n); - сравнение строк с указанием максимального размера * int toupper(int c); - преобразование символа к верхнему регистру * int tolower(int c); - преобразование символа к нижнему регистру * char *strchr(const char *s, int c); - поиск первого вхождения символа * char *strrchr(const char *s, int c); - поиск последнего вхождения символа * char *strstr(const char *haystack, const char *needle); - поиск подстроки
* int isalnum(int c); - является ли символ цифрой или буквой * int isalpha(int c); - является ли символ буквой * int isascii(int c); - принадлежит ли символ к набору ASCII * int isblank(int c); - является ли символ непечатаемым * int iscntrl(int c); - является ли символ управляющим * int isdigit(int c); - является ли символ цифрой * int isgraph(int c); - является ли символ печатаемым * int islower(int c); - является ли символ строчной буквой * int isprint(int c); - является ли символ печатаемым или пробелом * int ispunct(int c); - является ли символ печатаемым, но не буквой или цифрой * int isspace(int c); - является ли символ пробельным * int isupper(int c); - является ли символ заглавной буквой * int isxdigit(int c); - является ли символ шестнадцатиричной цифрой
Функции работы с памятью * void *calloc(size_t nmemb, size_t size); - выделяет память * void *malloc(size_t size); - выделяет память * void free(void *ptr); - освобождает память * void *realloc(void *ptr, size_t size); - выделяет блок памяти нового размера и копирует в него содержимое старого блока, старый блок удаляется * void *memcpy(void *dest, const void *src, size_t n); - копирование * void *memmove(void *dest, const void *src, size_t n); - копирование с учетом возможного наложения * int memcmp(const void *s 1, const void *s 2, size_t n); - сравнение * void *memset(void *s, int c, size_t n); - заполнение памяти указанным значением
Функции работы с файлами * int printf(const char *format, . . . ); - форматированная печать * int fprintf(FILE *stream, const char *format, . . . ); - форматированная печать в файл * int sprintf(char *str, const char *format, . . . ); - форматированная печать в буффер * int snprintf(char *str, size_t size, const char *format, . . . ); - форматированная печать в буффер с указанием размера буффера * int vprintf(const char *format, va_list ap); - форматированная печать списка аргументов * int vfprintf(FILE *stream, const char *format, va_list ap); - форматированная печать списка аргументов в файл * int vsprintf(char *str, const char *format, va_list ap); - форматированная печать списка аргументов в буффер * int vsnprintf(char *str, size_t size, const char *format, va_list ap); - форматированная печать списка аргументов в буффер с указанием размера буффера * FILE *fopen(const char *path, const char *mode); - открыть файл * FILE *freopen(const char *path, const char *mode, FILE *stream); - открыть файл и привязать его к файловой переменной stream * int fclose(FILE *fp); - закрыть файл
* void clearerr(FILE *stream); - очистить информацию об ошибке * int feof(FILE *stream); - проверить конец файла * int ferror(FILE *stream); - получить последнюю ошибку с файлом * int fileno(FILE *stream); - получить системный файловый идентификатор * FILE *stdin; - стандартный ввод * FILE *stdout; - стандартный вывод * FILE *stderr; - стандартный вывод ошибок * int fflush(FILE *stream); - сбросить все данные на носитель * int fpurge(FILE *stream); - очистить все внутренние буфферы * size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); - читать из файла * size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream); записывать в файл
* int fseek(FILE *stream, long offset, int whence); - перемещение указателя файла * long ftell(FILE *stream); - получить текущую позицию в файле * void rewind(FILE *stream); - перейти к началу файла * int fgetpos(FILE *stream, fpos_t *pos); - получить текущую позицию в файле * int fsetpos(FILE *stream, fpos_t *pos); - перемещение указателя файла * int fseeko(FILE *stream, off_t offset, int whence); - перемещение указателя файла * off_t ftello(FILE *stream); - получить текущую позицию в файле * char *tempnam(const char *dir, const char *pfx); - получить имя для временного файла * FILE *tmpfile(void); - создать и открыть временный файл * char *tmpnam(char *s); - получить имя для временного файла
* int fgetc(FILE *stream); - прочитать символ * char *fgets(char *s, int size, FILE *stream); - прочитать строку * int getc(FILE *stream); - прочитать символ * int getchar(void); - прочитать символ с stdin * char *gets(char *s); - прочитать строку с stdin * int ungetc(int c, FILE *stream); - положить символ обратно * int fputc(int c, FILE *stream); - записать символ * int fputs(const char *s, FILE *stream); - записать строку * int putc(int c, FILE *stream); - записать символ * int putchar(int c); - записать символ в stdout * int puts(const char *s); - записать строку в stdout
LECTURE #7
Функции работы с сетью * int socket(int domain, int type, int protocol); - создать сокет * int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); - ассоциировать сокет с адресом * int listen(int sockfd, int backlog); - задать размер очереди для входящих соединений * int connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen); - соединиться с удаленной стороной * int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); - принять соединение * int shutdown(int s, int how); - завершить работу с сокетом * int close(int fd); - закрыть сокет * ssize_t recv(int s, void *buf, size_t len, int flags); - принять данные * ssize_t recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen); - принять данные и узнать адрес с которого они были посланы * ssize_t recvmsg(int s, struct msghdr *msg, int flags); - принять данные * ssize_t send(int s, const void *buf, size_t len, int flags); - послать данные * ssize_t sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen); - послать данные на указанный адрес * ssize_t sendmsg(int s, const struct msghdr *msg, int flags); - послать данные
* ssize_t read(int fd, void *buf, size_t count); - принять данные * ssize_t write(int fd, const void *buf, size_t count); - послать данные * int getsockname(int s, struct sockaddr *name, socklen_t *namelen); получить имя сокета * int getpeername(int s, struct sockaddr *name, socklen_t *namelen); получить имя удаленной стороны * int fcntl(int fd, int cmd, . . . /* arg */ ); - управляющие функции * int ioctl(int d, int request, . . . ); - управляющие функции * int getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res); - получить информацию об адресе * void freeaddrinfo(struct addrinfo *res); - освободить структуру с информацией об адресе * int getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags); - получить информацию об имени
Функции работы с процессами * pid_t fork(void); - создание нового процесса * int execve(const char *filename, char *const argv[], char *const envp[]); выполнение файла * pid_t wait(int *status); - ждать завершения дочернего процесса * pid_t waitpid(pid_t pid, int *status, int options); - ждать завершения указанного дочернего процесса * int pipe(int pipefd[2]); - создать пару связанных дескрипторов вводавывода * FILE *popen(const char *command, const char *type); - запустить программу и перенаправить ее потоки ввода-вывода * int pclose(FILE *stream); - завершить программу, запущенную popen * int system(const char *command); - выполнить команду
LECTURE #8
POSIX-потоки ●pthread_create ●pthread_detach ●pthread_exit ●pthread_join pthread_mutex_init ●pthread_mutex_destroy ●pthread_mutex_lock ●pthread_mutex_timedlock ●pthread_mutex_trylock ●pthread_mutex_unlock ●
pthread_cond_init ●pthread_cond_destroy ●pthread_cond_signal ●pthread_cond_broadcast ●pthread_cond_wait ●pthread_cond_timedwait ●
References 1. * Брайан Керниган, Деннис Ритчи Язык программирования C. 2 -е издание, переработанное и дополненное, 2009. 2. * P. J. Plauger The standard C library 3. * Barr M. , Massa A. Programming embedded systems with C and GNU Development tools, O'Reilly Media, 2006 Copyright © 2011 DSR Corporation 82