Обход списка и переход к узлу по номеру от головы списка
Обход списка осуществляется с целью анализа, обработки и поиска данных находящихся в списке. Заметим, что переход к следующему узлу осуществляется присваиванием указателю C на текущий узел значения указателя на следующий узел cur->next. Но по определению списка, последний узел в списке содержит пустой указатель на следующий узел. А значит это и является признаком конца обхода списка. Таким образом, стандартный алгоритм обхода списка прост:
Выполнять в цикле:
1. Обработать текущий узел.
2. Перейти к следующему узлу.
До тех пор пока указатель на следующий узел станет пустым.
Пример 34. Напишем процедуру обохода списока с целью вывода его содержимого на экран и поиска совпадающей строки, а также функцию перехода к узлу списка по номеру.
void PrintSearchList (list head, int val)
//Head – указатель на голову списка, str – искомая строка
{
bool lfound = false; // признак того, что строка найдена
tail = &head; //начинаем с головы списка
while (tail != NULL)// если указатель на текущий элемент списка не пуст
{
printf("%d\n", tail->value); //выводим информационное поле списка
if (tail->value = val) lfound = true; //совпадает с искомой строкой?
tail = tail->next; //переходим к следующему узлу списка
}
if (lfound) printf("Элемент в списке найден!");
else printf("Элемент в списке не найден!");
}
list GotoNode (list head, int cnt)
//Cnt – номер узла, начиная с 1, к которому нужно перейти
{
int i = 1;
tail = &head;
while ((tail->next != NULL) && (i < cnt))
{
i++;
tail = tail->next;
}
return(*tail);
}
Стек, очередь, дек
Стеком (англ. stack) называется хранилище данных, в котором можно работать только с одним элементом: тем, который был добавлен в стек последним. Говорят, что стек реализует дисциплину обслуживания LIFO (Last In – First Out, последним пришел – первым ушел). Физически стек может быть реализован на основе массива или на основе односвязанного линейного списка, в котором все операции осуществляются только с головой списка. Этот элемент в стеке называется верхушкой стека и на него указывает указатель стека ptrStack (рис.43). Если указатель стека – пустой, то стек считается пустым.
Стек должен поддерживать следующие операции:
push – добавить (положить) в верхушку стека новый элемент;
pop – извлечь из верхушки стека элемент;
isEmpty – проверка, пуст ли стек;
top – узнать (прочитать) значение верхушки стека (не удаляя ее);
size – узнать количество элементов в стеке;
clear – очистить стек (удалить из него все элементы).
|
Поскольку стек с точки зрения программной реализации является частным случаем односвязного линейного списка, то на языке Паскаль стек можно описать с помощью следующих структур:
struct st // объявление типа stack
{
char info; информационная часть
struct st *ps; // указатель на предыдущий (более нижний) элемент стека
} stack;
Стек имеет очень широкое применение в программировании. Особенно часто он используется при решении системных задач, задач компиляции и анализа выражений. Рассмотрим наиболее характерный пример использования стека при переводе выражений в обратную польскую запись.
Обратная польская запись (ОПЗ) – это способ записи выражений (как правило алгебраических) в так называемом постфиксном (или суффиксном) виде, т.е. в таком виде, когда сначала записываются все операнды, а потом выполняемые над ними операции, т.е. для обычных бинарных операций сложения, вычитания, умножения и деления знак операции располагается после операндов, а не между ними как в привычном «инфиксном» виде. Одна из особенностей ОПЗ – отсутствие скобок, что позволяет вычислять ОПЗ за один проход слева направо. ОПЗ как правило используется в трансляторах и компиляторах для преобразования выражений в машинный код, их последующего вычисления, а также для анализа и трансляции синтаксических конструкций языка к виду, удобному для генерации машинного кода.
Пример 35. Представим выражение (a+b)/(c/a*c – e*d) в постфиксном виде:
ОПЗ: ab+ca/c*ed*–/. Вычислим ОПЗ слева на право, при вычислении пользуемся правилом: «в операции участвуют два операнда, расположенные слева от знака операции».
1. Первое вычисление: R1 = ab+ = a+b, подставляем в исходную строку вместо ab+ вычисленный результат R1получается ОПЗ: R1ca/c*ed*–/.
2. Второе действие: R2 = ca/ = c/a
ОПЗ: R1R2c*ed*–/
3. Третье действие: R3 = R2c* = R2*c = c/a*c
ОПЗ: R1R3ed*–/
4. Четвертое действие: R4 = ed* = e*d
ОПЗ: R1R3R4–/
5. Пятое действие: R5 = R3R4– = R3–R4 = c/a*c–e*d
ОПЗ: R1R5/
6. Шестое действие: R6 = R1R5/ = R1/R5=(a+b)/(c/a*c–e*d)
ОПЗ: R6
ОПЗ вычислено и его значением стало значение выражения R6.
Наиболе известным алгоритмом перевода простого алгебраического выражения в ОПЗ является алгоритм Дейкстры (Э́дсгер Ви́бе Де́йкстра, 1930–2002, – выдающийся нидерландский ученый, идеи которого оказали огромное влияние на развитие компьютерной индустрии). Идея алгоритма основывается на использовании стека и анализе приоритета операций и заключается в следующем:
1. Исходная строка просматривается посимвольно, слева направо до достижения конца строки.
2. Если встречается символ операция, то эта операция при определенных условиях помещается в стек (затем при определенных условиях операции выталкиваются в выходную строку).
3. Если встречаются символы операндов, то они из входной строки поступают сразу в выходную строку.
4. Если встречается открывающаяся скобка, то она всегда помещается в стек.
5. Закрывающаяся скобка ни в стек, ни в выходную строку не помещается. Когда она встречается во входной строке, то из стека выталкиваются все символы до первой встречной открывающейся скобки включительно. При этом знаки операций выталкиваются в выходную строку, а открывающаяся скобка просто удаляется из стека.
6. Необходимо использовать следующие приоритеты операций (табл. 17). Чем больше значение приоритета, тем сильнее операция связывает операнды:
Таблица 17.
Приоритеты операций для вычисления ОПЗ
Операции | ( | + | – | * | / |
Приоритет |
7. Если во входной строке текущий символ – знак операции, то сравниваются приоритеты операций из строки и верхушки стека.
8. Если приоритет операции из входной строки больше приоритета операции из верхушки стека, то операция из входной строки стека перемещается в стек.
9. В противном случае из стека выталкиваются все операции с приоритетами большими либо равными приоритету операции из входной строки. После чего операция из входной строки помещается в стек.
10. При встрече конца входной строки содержимое стека выталкивается в выходную строку.
Пример 36.Напишем программу перевода входной строки в ОПЗ.
/* Описание стpуктуpы(элемента стека) */
struct st
{
char c;
struct st *next;
};
struct st *push(struct st *, char);
/* Пpототипы функций */
char DEL(struct st **);
int PRIOR(char);
void main(void)
{
// Стек опеpаций пуст
struct st *OPERS = NULL;
char a[80], outstring[80];
int k, point;
do
{
puts("Введите выражение (в конце поставте '=') : ");
fflush(stdin);
// Ввод аpифметического выpажения
gets(a);
k = point = 0;
// Повтоpяем , пока не дойдем до '='
while(a[k] != '\0' && a[k] != '=')
{
if(a[k] == ')') // Если очеpедной символ - ')', то выталкиваем из
// стека в выходную стpоку все знаки опеpаций до
// ближайшей откpывающей скобки
{
while((OPERS->c) != '(')
outstring[point++] = DEL(&OPERS);
DEL(&OPERS); // Удаляем из стека саму откpывающую скобку
}
if(a[k] >= 'a' && a[k] <= 'z') // Если очеpедной символ - буква , то
// пеpеписываем её в выходную стpоку
outstring[point++] = a[k];
if(a[k] == '(') // Если очеpедной символ - '(' , то заталкиваем её
//в стек
OPERS = push(OPERS, '(');
// Если следующий символ - знак опеpации , то:
if(a[k] == '+' || a[k] == '-' || a[k] == '/' || a[k] == '*')
{
if(OPERS == NULL) // если стек пуст записываем в него опеpацию
OPERS = push(OPERS, a[k]);
else // если не пуст
// если пpиоpитет поступившей опеpации больше пpиоpитета опеpации на веpшине стека заталкиваем поступившую опеpацию на стек
if(PRIOR(OPERS->c) < PRIOR(a[k]))
OPERS = push(OPERS, a[k]); //
else // если пpиоpитет меньше пеpеписываем в выходную стpоку все
// опеpации с большим или pавным пpиоpитетом
{
while((OPERS != NULL) && (PRIOR(OPERS->c) >= PRIOR(a[k]))) //
outstring[point++] = DEL(&OPERS);
OPERS = push(OPERS, a[k]); // записываем в стек поступившую
// опеpацию
}
}
k++; // Пеpеход к следующему символу входной стpоки
}
// После pассмотpения всего выpажения пеpеписываем все опеpации из стека в выходную стpоку и печатаем её
while(OPERS != NULL)
outstring[point++] = DEL(&OPERS);
outstring[point] = '\0';
printf("\n%s\n", outstring);
fflush(stdin);
puts("\Повторить (y/n)?");
}
while(getchar() != 'n');
}
/* Функция push записывает на стек (на веpшину котоpого указывает HEAD)
символ a. Возвpащает указатель на новую веpшину стека */
struct st *push(struct st *HEAD, char a)
{
st* PTR = new st; // Выделение памяти
PTR->c = a; // Инициализация созданной веpшины
PTR->next = HEAD; // Подключение её к стеку
return PTR;// PTR - новая веpшина стека
}
/* Функция DEL удаляет символ с веpшины стека.
Возвpащает удаляемый символ. Изменяет указатель на веpшину стека */
char DEL(struct st **HEAD)
{
struct st *PTR;
char a;
if(*HEAD == NULL) return '\0'; // Если стек пуст, возвpащается '\0'
PTR = *HEAD; // в PTR - адpес веpшины стека
a = PTR->c;
*HEAD = PTR->next; // Изменяем адpес веpшины стека
free(PTR); // Освобождение памяти
return a; // Возвpат символа с веpшины стека
}
// Функция PRIOR возвpащает пpиоpитет аpифметической опеpации
int PRIOR(char a)
{
switch(a)
{
case '*':
case '/':
return 3;
case '-':
case '+':
return 2;
case '(':
return 1;
}
}
Приведем пример использования Алгоритма Дейкстры для входной строки (a+b*c)*(a–b)/(d–(a+b*d)). Для удобства отображения стека в таблице «транспонируем» его, т.е. разместим стек в строке, развернув по часовой стрелке на 90 градусов, так чтобы вершина стека располагалась в конце строки справа (табл.18).
В программировании, кроме списков и стека часто используются подобные динамические структуры, программная реализация которых похожа на списки и стек, но дисциплина доступа к ним и набор типовых операций несколько видоизменены, к ним относятся очередь и дек.
Очередью (aнгл. queue) называется структура данных, в которой элементы кладутся в конец, а извлекаются из начала. Таким образом, первым из очереди будет извлечен тот элемент, который будет добавлен раньше других. Говорят, что очередь реализует дисциплину обслуживания FIFO (First In – First Out, первым пришел – первым ушел). Очередь можно рассматривать как однонаправленный список, в котором можно удалять только из начала, а добавлять только в конец. Основные операции над очередью – такие же, что и над стеком: включение, исключение, определение размера, очистка, обход, чтение.
Деком (англ. deque – аббревиатура от double-ended queue, двухсторонняя очередь) называется структура данных, в которую можно удалять и добавлять элементы как в начало, так и в конец. Дек хранится в памяти так же, как и очередь. Таким образом, дек может быть и стеком, и очередью, и комбинацией этих структур. Наиболее часто дек представляется структурой с ограничением на вход или выход: дек с ограниченным входом (только одна позиция доступна для добавления элемента) и дек с ограниченным выходом (только одна позиция доступна для взятия элемента из дека). Стандартные операции над деком: включение элемента справа; включение элемента слева; исключение элемента справа; исключение элемента слева; определение размера; очистка.
На практике также используются модификации приведенных структур, например циклическая очередь, замкнутый или кольцевой список и т.п. В таких структурах, как правло последний элемент замыкается указателем на первый (и наоборот, – первый ссылается на последний, при двухсторонней связи), что позволяет рассматривать структуру как замкнутое кольцо.
Деревья
Дерево – одна из наиболее распространённых структур данных, используемых в программировании. Формально дерево определяется рекурсивно следующим образом: это конечное множество Т, состоящее из одного или более узлов таких, что:
1. Имеется один узел, называемый корнем дерева.
2. Остальные узлы, исключая корень, содержатся в m≥0 попарно непересекающихся множествах Т1, Т2,….Тm, каждое из которых в свою очередь является деревом. При этом деревья Т1, Т2,….Тm называются поддеревьями (потомками) данного корня.
Поддеревья некоторой вершины еще иногда называют кустами, а конечные вершины дерева из которых больше не выходит ни одной связи (т.е. для такого узла m=0), называют листьями.
Наиболее распространены в программировании бинарные (двоичные) деревья, в которых каждый узел может иметь не более двух потомков. Рекурсивное определение бинарного дерева задает его как корень и два бинарных поддерева: левое и правое, – причем любое из них может быть пустым. Бинарные деревья используются как структура данных в том случае, когда в каждой точке процесса должно быть принято одно из двух возможных решений. Например, они применяются для синтаксического анализа, поиска, сортировки, управления базами данных и в других приложениях.
Пример 37. Приведем пример бинарного дерева (рис.44), которое может использоваться для вычисления алгебраического выражения (A*B+C*D)/(B*C), если двигаться от листьев дерева к корню.
|
Бинарные деревья наиболее часто используются в программировании. Это основывается на том факте, что любое дерево может быть приведено к бинарному. Основное правило такого преобразования: левая ветвь каждого узла соединяет его с первым узлом следующего уровня, а правая – с другими узлами следующего уровня (братьями). Рис.45 демонстрирует первый шаг преобразования дерева A к его бинарному представлению. На втором шаге тоже самое делается с поддеревом B и т.д.
| |||
Рис.45. Шаг преобразования дерева к бинарному |
Бинарное дерево на языке Си может быть описано следующими структурами данных:
struct tree
{
int info; //информационное поле
tree ltree,rtree; //указатели на левое и правое поддерево
}
К бинарным деревьям применяют следующие типовые операции:
1. Создание нового бинарного дерева, состоящего из одного узла с информационным полем .
2. Создание нового левого или правого «сына» (узла) для текущего узла.
3. Чтение информационного содержимого узла.
4. Определение указателя на левое или правое поддерево.
5. Удаление куста или листа дерева.
6. Удаление левого или правого поддерева для узла.
7. Обход дерева.
8. Сравнение деревьев.
9. Соединение деревьев.
Пример 40. Рассмотрим реализацию основных процедур и функции для работы с деревьями.
tree MakeTree(tree node, int x)
{
if(node.value == NULL)
{
tree* p = new tree;
p->value = x;
node = *p;
}
else
{
if((node).value > x) MakeTree(*node.pleft, x);
else MakeTree(*node.pright, x);
}
return node;
}
void SetLeft (tree *p,int x) // создание левого сына для узла с указателем p
{
*p->ltree = NewNode(x);
}
void SetRight(tree *p,int x) // создание правого сына для узла с указателем p
{
*p->rtree = NewNode(x);
}
int GetInfo (tree *p) // чтение значения информационного поля узла p
{
if (p != NULL) return p->info;
else return(0);
}
tree GetLeftTree (tree *p) // выдать значение указателя на левое поддерево
// узла p
{
if (p != NULL) return *p->ltree;
//else return(NULL);
}
tree GetRightTree (tree *p) //выдать значение указателя на правое поддерево
// узла p
{
if (p != NULL) return *p->ltree;
// else return (tree)NULL;
}
void DelLeaf (tree *p) // Удалить в дереве «лист»
{
if (p != NULL) free(p);
}
Рассмотрим более подробно задачу обхода дерева. Обход дерева – это последовательный обход всех узлов дерева. Фактически во время обхода нужно составить список всех узлов дерева. Поскольку дерево по определению является рекурсивной структурой данных, то и обход дерева как правило осуществляется рекурсивно. Существует три способа рекурсивного обхода бинарного дерева: обход с префиксным порядком; обход с инфиксным порядком; обход с суффиксным (или постфиксным) порядком.
Префиксный порядок обхода дерева определяется в виде списка узлов следующим образом:
Если дерево не пусто, то префиксный порядок это:
1. Корень дерева.
2. Узлы левого поддерева в префиксном порядке.
3. Узлы правого поддерева в префиксном порядке.
Например, пусть дано дерево, указанное вна рис. примере 48, тогда префиксный обход дерева это следующая последовательность узлов: /+*AB*CD*BC. Иногда префиксный порядок называют обходом дерева сверху вниз.
Инфиксный порядок обхода дерева определяется в виде списка узлов следующим образом:
Если дерево не пусто, то инфиксный порядок это:
1. Узлы левого поддерева в инфиксном порядке.
2. Корень дерева.
3. Узлы правого поддерева в инфиксном порядке.
Для нашего примера это будет: A*B+C*D/B*C
Суффиксный порядок обхода дерева определяется в виде списка узлов следующим образом:
Если дерево не пусто, то суффиксный порядок это:
1. Узлы левого поддерева в суффиксном порядке.
2. Узлы правого поддерева в суффиксном порядке.
3. Корень дерева.
Для нашего примера это будет: AB*CD*+BC*/. Суффиксный порядок обхода иногда называют обходом дерева снизу вверх.
Заметим, что инфиксный порядок обхода бинарного дерева в нашем примере совпал с самим алгебраическим выражением, только без скобок, суффиксный порядок – совпал с ОПЗ выражения, а результат префиксного обхода является обратным инфиксному, т.е. сначала указывается операция, затем операнды, – именно так записываются функции и процедуры на языке Паскаль. С обходом дерева как правило совмещаются некоторые действия над проходимой вершиной. Например, в случае суффиксного обхода, можно совместить обход с операцией удаления куста дерева.
void PrefixObhod (tree *p)
{
if (p !=NULL) // Если дерево не пусто, то префиксный порядок это:
{
printf ("%d", p->info); //обработка узла, например напечатем его инф.часть
PrefixObhod (p->ltree); // Узлы левого поддерева в префиксном порядке
PrefixObhod (p->rtree); // Узлы правого поддерева в префиксном порядке
}
}
void InfixObhod (tree *p)
{
if (p != NULL) // Если дерево не пусто, то инфиксный порядок это:
{
InfixObhod (p->ltree); // Узлы левого поддерева в инфиксном порядке
printf ("%d", p->info); //обработка узла, например напечатем его инф.часть
InfixObhod (p->rtree); // Узлы правого поддерева в инфиксном порядке
}
}
void DelSubTree (tree *p) //процедура удаление куста p с использованием суффиксного обхода
{
if (p != NULL) // Если дерево не пусто, то суффиксный порядок это:
{
DelSubTree (p->ltree); // Узлы левого поддерева в суффиксном порядке
DelSubTree (p->rtree); // Узлы правого поддерева в суффиксном порядке
free(p); //обработка узла, например удалим узел
}
}
void DelLeftTree (tree *p) //удаление левого поддерева для узла p
{
if (p != NULL)
{
DelSubTree (p->ltree);
p->ltree = NULL;
}
}
void DelRightTree (tree *p) //удаление правого поддерева для узла p
{
if (p != NULL)
{
DelSubTree (p->rtree);
p->ltree = NULL;
}
}
Сравнение деревьев производится путём сравнения информационной части (информационных полей) соответствующих деревьев, начиная с корня. Функция должна сравнивать информационные части узлов дерева, а далее рекурсивно сравнивать левые и правые поддеревья. Фактически функция осуществляет обход дерева сверху вниз. Выходом из рекурсии в данном случае будет сравнение значений указателей (в том числе и пустых). Для равных деревьев одновременно указатели будут обнулены и станут равными. В случае различия, это равенство не пройдет. Если же оба указателя отличны от пустых, т.е. указывают на поддеревья, то сравниваются их информационные части и соответственно левые и правые потомки. Если все эти три сравнения совпадают, то делается заключение о совпадении сравниваемых деревьев.
Напишем функцию, которая будет выдавать истинное значение, если два дерева равны, и ложное значение в противном случае.
bool TreeEqual(tree *p1, tree *p2)
{
if (p1 == p2) return true;
else
if ((p2 != NULL) && (p1 != NULL))
return ((p1->info = p2->info) && TreeEqual(p1->ltree, p2->ltree) &&
TreeEqual(p1->rtree, p2->rtree));
else return false;
}
Приложение 1. Стандартные библиотеки языка Си
В языке Си стандартные функции собраны в различных библиотеках. Для использования этих функций необходимо подключить к проекту соотаетствующие библиотеки с помощью конструкции #include. Ниже представлены некоторые библиотеки языка Си, а также их состав.
Таблица 19.
Библиотеки языка Си
Имя | Назначение библиотеки |
complex.h | Набор функций для работы с комплексными числами |
ctype.h | Содержит функции, используемые для классификации символов по их типам или для конвертации между верхним и нижним регистрами независимо от используемой кодировки |
errno.h | Для проверки кодов ошибок, возвращаемых библиотечными функциями |
iostream | Содержит функции контроля чтения и записи стандартных потоков |
limits.h | Содержит заранее заданные константы, определяющие специфику реализации свойств целых типов |
signal.h | Функции для управления различными исключительными условиями |
math.h | Функции для вычисления основных математических функций |
stdio.h | Реализует основные возможности ввода и вывода в языке Си |
stdlib.h | Вспомогательные функции, которые могут быть использованы в разнообразных программах |
string.h | Для работы с различными видами строк |
time.h | Для конвертации между различными форматами времени и даты |
Таблица 20.
Состав библиотеки complex.h
Имя функции | Описание |
cabs, cabsf, cabsl | Абсолютное значение комплексного числа |
cacos, cacosf, cacosl | Комплексный арккосинус |
cacosh, cacoshf, cacoshl | Комплексный гиперболический арккосинус |
carg, cargf, cargl | Аргумент комплексного числа |
casin, casinf, casinl | Комплексный арксинус |
casinh, casinhf, casinhl | Комплексный гиперболический арксинус |
catan, catanf, catanl | Комплексный арктангенс |
catanh, catanhf, catanhl | Комплексный гиперболический арктангенс |
ccos, ccosf, ccosl | Комплексный косинус |
ccosh, ccoshf, ccoshl | Комплексный гиперболический косинус |
cexp, cexpf, cexpl | Комплексная экспонента |
cimag, cimagf, cimagl | Мнимая часть комплексного числа |
clog, clogf, clogl | Натуральный логарифм комплексного числа |
conj, conjf, conjl | Комплексное сопряжённое число |
cpow, cpowf, cpowl | Степень комплексного числа |
cproj, cprojf, cprojl | Проекция на римановскую сферу |
creal, crealf, creall | Действительная часть комплексного числа |
csin, csinf, csinl | Комплексный синус |
csinh, csinhf, csinhl | Комплексный гиперболический синус |
csqrt, csqrtf, csqrtl | Комплексный квадратный корень |
ctan, ctanf, ctanl | Комплексный тангенс |
ctanh, ctanhf, ctanhl | Комплексный гиперболический тангенс |
Таблица 21.
Состав библиотеки ctype.h
Имя функции | Проверяет, является ли аргумент… |
isalnum | …буквой или цифрой |
isalpha | …буквой |
iscntrl | …управляющим символом |
isdigit | …цифрой |
isgraph | …символом, имеющим графическое представление |
islower | …буквой в нижнем регистре |
isprint | …символом, который может быть напечатан |
ispunct | …символом, имеющим графическое представление, но не являющимся при этом буквой или цифрой |
isspace | …разделительным символом |
isupper | …буквой в верхнем регистре |
isxdigit | …цифрой шестнадцатиричной системы счисления |
Таблица 22.
Состав библиотеки errno.h
Имя функции | Описание |
E2BIG | Список аргументов слишком длинный |
EACCES | Отказ в доступе |
EAGAIN | Ресурс временно недоступен |
EBADF | Неправильный дескриптор файла |
EBADMSG | Неправильное сообщение |
EBUSY | Ресурс занят |
ECANCELED | Операция отменена |
ECHILD | Нет дочернего процесса |
EDEADLK | Обход тупика ресурсов |
EDOM | Ошибка области определения |
EEXIST | Файл существует |
EFAULT | Неправильный адрес |
EFBIG | Файл слишком велик |
EINPROGRESS | Операция в процессе выполнения |
EINTR | Прерванный вызов функции |
EINVAL | Неправильный аргумент |
EIO | Ошибка ввода-вывода |
EISDIR | Это каталог |
EMFILE | Слишком много открытых файлов |
EMLINK | Слишком много связей |
EMSGSIZE | Неопределённая длина буфера сообщения |
ENAMETOOLONG | Имя файла слишком длинное |
ENFILE | Слишком много открытых файлов в системе |
ENODEV | Нет такого устройства |
ENOENT | Нет такого файла в каталоге |
ENOEXEC | Ошибка формата исполняемого файла |
ENOLCK | Блокировка недоступна |
ENOMEM | Недостаточно памяти |
ENOSPC | Памяти на устройстве не осталось |
ENOSYS | Функция не реализована |
ENOTDIR | Это не каталог |
ENOTEMPTY | Каталог непустой |
ENOTSUP | Не поддерживается |
ENOTTY | Неопределённая операция управления вводом-выводом |
ENXIO | Нет такого устройства или адреса |
EPERM | Операция не разрешена |
EPIPE | Разрушенный канал |
ERANGE | Результат слишком велик |
EROFS | Файловая система только на чтение |
ESPIPE | Неправильное позиционирование |
ESRCH | Нет такого процесса |
ETIMEDOUT | Операция задержана |
EXDEV | Неопределённая связь |
Таблица 23.
Состав библиотеки iostream.h
Имя функции | Описание |
cin | Соответствует стандартному вводу. В общем случае он позволяет читать данные с терминала пользователя |
cout | Соответствует стандартному выводу. В общем случае он позволяет выводить данные на терминал пользователя |
cerr | Соответствует стандартному выводу для ошибок. В этот поток мы направляем сообщения об ошибках программы |
Таблица 24.
Состав библиотеки limits.h
Имя | Описание | Типичное значение 32-битной программы | Типичное значение 64-битной программы | Стандартный минимум или максимум диапазона значений |
CHAR_BIT | Число бит в байте | ≥ 8 | ||
SCHAR_MIN | Минимальное значение для знакового char | −128 | −128 | ≤ -127 |
SCHAR_MAX | Максимальное значение для знакового char | +127 | +127 | ≥ +127 |
UCHAR_MAX | Максимальное значение для беззнакового char | +255 | +255 | ≥ +255 |
CHAR_MIN | Минимальное значение для char | −128 | −128 | ≤ -127(если char представлено как знаковый char; иначе 0) |
CHAR_MAX | Максимальное значение для char | +127 | +127 | ≥ +127 (если char представлено как знаковый char; иначе +255) |
MB_LEN_MAX | Максимальная многобайтовая длина символа по всем локалям | различается, обычно от 4 | различается, обычно от 4 | ≥ 1 |
SHRT_MIN | Минимальное значение для short int | −32,768 | −32,768 | ≤ -32,767 |
SHRT_MAX | Максимальное значение для short int | +32,767 | +32,767 | ≥ +32,767 |
USHRT_MAX | Максимальное значение для беззнакового short int | +65,535 | +65,535 | ≥ +65,535 |
INT_MIN | Минимальное значение для int | −2,147,483,648 | −2,147,483,648 | ≤ -32,767 |
INT_MAX | Максимальное значение для int | +2,147,483,647 | +2,147,483,647 | ≥ +32,767 |
UINT_MAX | Максимальное значение для беззнакового int | +4,294,967,295 | +4,294,967,295 | ≥ +65,535 |
LONG_MIN | Минимальное значение для long int | −2,147,483,648 | −9,223,372,036,854,775,808 | ≤ -2,147,483,647 |
LONG_MAX | Максимальное значение для long int | +2,147,483,647 | +9,223,372,036,854,775,807 | ≥ +2,147,483,647 |
ULONG_MAX | максимальное значение для беззнакового long int | +4,294,967,295 | +18,446,744,073,709,551,615 | ≥ +4,294,967,295 |
LLONG_MIN | Минимальное значение для long long int | −9,223,372,036,854,775,808 | −9,223,372,036,854,775,808 | ≤ -9,223,372,036,854,775,807 |
LLONG_MAX | Максимальное значение для long long int | +9,223,372,036,854,775,807 | +9,223,372,036,854,775,807 | ≥ +9,223,372,036,854,775,807 |
ULLONG_MAX | максимальное значение для беззнакового long long int | +18,446,744,073,709,551,615 | +18,446,744,073,709,551,615 | ≥ +18,446,744,073,709,551,615 |
Таблица 25.
Состав библиотеки limits.h
Константа | Значение | Стандарты |
SIGHUP | Отбой | POSIX |
SIGINT | Прерывание | ANSI |
SIGQUIT | Выход | POSIX |
SIGILL | Недопустимая инструкция | ANSI |
SIGABRT | Самоостановка | ANSI |
SIGTRAP | Перехват события | POSIX |
SIGIOT | Перехват ввода-вывода | 4.2 BSD |
SIGEMT | Перехват эмуляции | 4.2 BSD |
SIGFPE | Исключение с плавающей запятой | ANSI |
SIGKILL | Неперехватываемый сигнал завершения | POSIX |
SIGBUS | Ошибка шины | 4.2 BSD |
SIGSEGV | Нарушение сегментации | ANSI |
SIGSYS | Неправильный аргумент в системный вызов | 4.2 BSD |
SIGPIPE | Нарушение канала | POSIX |
SIGALRM | Истечение времени | POSIX |
SIGTERM | Заверешние | ANSI |
SIGUSR1 | Пользовательский сигнал 1 | POSIX |
SIGUSR2 | Пользовательский сигнал 2 | POSIX |
SIGCHLD | Изменение статуса дочернего процесса | POSIX |
SIGCLD | Аналогично SIGCHLD | System V |
SIGPWR | Перезапуск после проблемы с питанием | System V |
SIGXCPU | Ограничение процессорного времени | POSIX |
Таблица 26.
Состав библиотеки math.h
Имя функции | Описание |
acos | арккосинус |
asin | арксинус |
atan | арктангенс |
atan2 | арктангенс с двумя параметрами |
ceil | округление до ближайшего большего целого числа |
cos | косинус |
cosh | гиперболический косинус |
exp | вычисление экспоненты |
fabs | абсолютная величина (числа с плавающей точкой) |
floor | округление до ближайшего меньшего целого числа |
fmod | вычисление остатка от деления нацело для чисел с плавающей точкой |
frexp | разбивает число с плавающей точкой на мантиссу и показатель степени. |
ldexp | умножение числа с плавающей точкой на целую степень двух |
log | натуральный логарифм |
log10 | логарифм по основанию 10 |
modf(x,p) | извлекает целую и дробную части (с учетом знака) из числа с плавающей точкой |
pow(x,y) | результат возведения x в степень y, xy |
sin | синус |
sinh | гиперболический синус |
sqrt | квадратный корень |
tan | тангенс |
tanh | гиперболический тангенс |
Таблица 27.
Состав библиотеки stdio.h
Имя функции | Описание |
Функции для файловых операций | |
fclose | закрывает файл, ассоциированный с переданным ей значением FILE * |
fopen, freopen, fdopen | открывают файл для определенных типов чтения и записи |
remove | удаляет файл (стирая его) |
rename | переименовывает файл |
rewind | работает аналогично fseek(stream, SEEK_SET), вызванному для потока, со сбросом индикатора ошибок |
tmpfile | создает и открывает временный файл, удаляемый при закрытии через fclose() |
Функции для операций ввода-вывода | |
clearerr | очищает EOF и индикаторы ошибок для данного потока |
feof | проверяет, установлен ли индикатор EOF для данного потока |
ferror | проверяет, установлен ли индикатор ошибок для данного потока |
fflush | принудительно записывает вывод, предназначенный для помещения в буфер, в файл, ассоциированный с данным потоком |
fgetpos | сохраняет позицию указателя файла потока, ассоциированный с его первым аргументом (FILE *), в его второй аргумент (fpos_t *) |
fgetc | возвращает один символ из файла |
fgets | получает строку из файла (оканчивающуюся символом перевода строки или конца файла) |
fputc | записывает один символ в файл |
fputs | записывает строку в файл |
ftell | возвращает указатель позиции файла, который может быть передан fseek |
fseek | производит поиск по файлу |
fsetpos | устанавливает указатель позиции файла потока, ассоциированный с его первым аргументом (FILE *), как хранимый во втором его аргументе (fpos_t *) |
fread | читает данные из файла |
fwrite | записывает данные в файл |
getc | считывает и возвращает символ из данного потока и изменяет укащатель позиции файла; позволяет использоваться как макрос с теми же эффектами, что и fgetc, кроме того, что может вычислять поток более одного раза |
getchar | имеет аналогичный эффект, что и getc(stdin) |
gets | считывает символы из stdin до символа перевода строки и хранит их в своем единственном аргументе |
printf, vprintf | используются для вывода в стандартный поток вывода |
fprintf, vfprintf | используются для вывода в файл |
sprintf, snprintf, vsprintf | используются для вывода в массив типа char (Строка в языке Си) |
perror | записывает сообщение об ошибке в stderr |
putc | записывает и возвращает символ в поток и изменяет указатель позиции файла на него; можно использовать как макрос с теми же свойствами, что и fputc, кроме того, что он может обрабатывать поток более одного раза |
putchar, fputchar | аналогичны putc(stdout) |
scanf, vscanf | используются для ввода из стандар Наши рекомендации
|