
- •Часть 1
- •Общие сведения Сведения об эумк
- •Методические рекомендации по изучению дисциплины
- •Рабочая учебная программа
- •Учреждение образования
- •«Белорусский государственный университет
- •Информатики и радиоэлектроники»
- •Часть 2 __184__
- •Содержание дисциплины
- •1. Индивидуальные практические занятия, их характеристика
- •2. Контрольные работы, их характеристика
- •3. Курсовой проект, его характеристика
- •4. Литература
- •4.1. Основная
- •4.2. Дополнительная
- •5. Перечень компьютерных программ, наглядных и других пособий, методических указаний и материалов и технических средств обучения
- •Протокол согласования учЕбной программы по изучаемой учебной дисциплине с другими дисциплинами специальности
- •Теоретический раздел Введение
- •1. Основные типы данных
- •1.1. Общие сведения
- •1.2. Данные типа int
- •1.3. Данные типа char
- •1.4. Модификаторы доступа const и volatile
- •1.5. Данные вещественного типа (с плавающей точкой)
- •1.6. Элементарный ввод-вывод
- •1.7. Структура простой программы на языке Си
- •2. Операции и выражения
- •2.1. Выражение и его интерпретация
- •2.2. Основные операции
- •2.2.1. Арифметические операции
- •2.2.2. Побитовые логические операции
- •2.2.3. Операции сдвига
- •2.2.4. Операция присваивания
- •2.2.5. Операция sizeof
- •2.2.6. Преобразование типов в выражениях
- •2.2.7. Операция преобразования типов
- •2.2.8. Приоритеты в языке Си
- •3. Операторы управления вычислительным процессом
- •3.1. Оператор if
- •3.2. Операции отношения
- •3.3. Логические операции
- •3.4. Операция запятая
- •3.5. Операция условия ?:
- •3.6. Оператор безусловного перехода goto
- •3.7. Оператор switch
- •`` ` `3.8. Операторы цикла
- •3.8.1. Оператор for
- •3.8.2. Оператор while
- •3.8.3. Оператор do...While
- •3.9. Оператор break
- •3.10. Оператор continue
- •4. Массивы и указатели
- •4.1. Одномерные массивы и их инициализация
- •4.2. Многомерные массивы и их инициализация
- •4.3. Объявление указателей
- •4.4. Операции над указателями
- •1) Взятие адреса
- •2) Косвенная адресация или разыменование указателя
- •3) Увеличение или уменьшение значения указателя на целое число
- •4) Разность указателей
- •5) Сравнение указателей
- •6) Присваивание указателей друг другу
- •4.6. Связь между указателями и массивами
- •4.7. Динамическое распределение памяти
- •4.8. Массивы указателей
- •5. Функции
- •5.1. Общие сведения
- •5.2. Область видимости переменных
- •5.2.1. Локальные переменные
- •5.2.2. Глобальные переменные
- •5.3. Передача параметров в функцию
- •5.4. Рекурсивные функции
- •5.5. Использование функций в качестве параметров функций
- •5.6. Указатели на функции
- •5.7. Структура программы на Си
- •5.8. Передача параметров в функцию main()
- •6. Строки
- •7. Классы хранения и видимость переменных
- •7.1. Общие сведения
- •7.2. Автоматический класс хранения (auto)
- •7.3. Регистровый класс хранения (register)
- •7.4. Статический класс хранения (static)
- •7.5. Внешний класс хранения (extern)
- •7.6. Заключение
- •8. Структуры, объединения и перечисления
- •8.1. Общие сведения
- •8.2. Инициализация структурных переменных
- •8.3. Вложенные структуры
- •8.4. Указатели на структуры
- •8.5. Массивы структурных переменных
- •8.6. Передача функциям структурных переменных
- •8.7. Оператор typedef
- •8.8. Поля битов в структурах
- •8.9. Объединения
- •8.10. Перечисления
- •9. Динамические структуры данных
- •9.1. Общие сведения
- •9.2. Связные списки
- •9.2.1. Односвязные списки
- •9.2.2. Двусвязные списки
- •9.2.3. Циклические списки
- •9.3. Стеки
- •9.4. Очереди
- •9.5. Деревья
- •9.5.1. Понятие графа
- •9.5.2. Бинарные деревья
- •10. Файлы
- •10.1. Общие сведения
- •10.2. Открытие и закрытие файлов
- •10.3. Функции ввода-вывода для работы с текстовыми файлами
- •10.4. Произвольный доступ к файлу
- •10.5. Функции ввода-вывода для работы с бинарными файлами
- •11. Директивы препроцессора
- •11.1. Основные понятия
- •11.2. Директива #include
- •11.3. Директивы препроцессора #define и #undef
- •11.3.1. Символические константы
- •11.3.2. Макросы с параметрами
- •11.3.3. Директива #undef
- •11.4. Условная компиляция
- •11.5. Директивы # и ##
- •12. Модульное программирование
- •13. Введение в объектно-ориентированное программирование
- •13.1. Постановка задачи
- •13.2. Решение задачи средствами Си
- •13.5. Наследование
- •13.6. Перегрузка
- •13.7. Ссылочный тип
- •Литература
- •Приложение 1. Рекомендации по оформлению текстов программ
- •Тесты к теоретическому разделу Вопросы к разделу 1. Основные типы данных
- •Вопросы к разделу 2. Операции и выражения
- •Вопросы к разделу 3. Операторы управления вычислительным процессом
- •Вопросы к разделу 4. Массивы и указатели
- •Вопросы к разделу 5. Функции
- •Вопросы к разделу 6. Строки
- •Вопросы к разделу 7. Классы хранения и видимость переменных
- •Вопросы к разделу 8. Структуры, объединения и перечисления
- •Вопросы к разделу 9. Динамические структуры данных
- •Вопросы к разделу 10. Файлы
- •Вопросы к разделу 11. Директивы препроцессора
- •Вопросы к разделу 12. Модульное программирование
- •Вопросы к разделу 13. Введение в ооп
- •Правильные ответы на вопросы тестов к теоретическому разделу
- •Вопросы к теоретическому зачету
- •Варианты индивидуальных заданий
- •Контрольная работа №2
- •Варианты индивидуальных заданий
- •Индивидуальные практические работы Указания к выбору варианта индивидуальных практических работ
- •Индивидуальная практическая работа № 1. Массивы и строки
- •Варианты индивидуальных заданий
- •Индивидуальная практическая работа № 2. Динамические структуры данных
- •Варианты индивидуальных заданий
9.2.2. Двусвязные списки
Двусвязный список представляет собой последовательность связанных узлов, каждый из которых, в отличие от однонаправленного списка, содержит поле данных и два указателя, один из которых содержит адрес памяти, где хранится следующий элемент списка, а второй – адрес памяти, где хранится предыдущий элемент списка. Это дает возможность перемещаться по списку как с начала в хвост, так и с хвоста в начало.
На рис 9.3 изображен двусвязный список, каждый узел которого включает в себя поле данных типа char, указатель на следующий элемент – nextPtr и указатель на предыдущий элемент – predPtr. Указатель на начало списка – HeadPtr, на конец – LastPtr.
Рис. 9.3. Двусвязный список
9.2.3. Циклические списки
Циклические связные списки отличаются от обычных только одним: последний узел ссылается не в NULL, а на первый узел данного списка, то есть на «начало» списка. Пустой циклический список, таким образом, содержит единственный узел, который указывает сам на себя. При добавлении элементов, последний узел будет указывать на первый узел (рис. 9.4).
Циклические списки во многом значительно упрощают разработку алгоритмов.
-
а) однонаправленный связный циклический список
б) двусвязный циклический список
Рис. 9.4. Циклические списки
9.3. Стеки
Стек представляет собой упорядоченный набор элементов, доступ к которым осуществляется только с одного конца, называемого вершиной стека. Проще говоря, стек – это вид связного списка, вставку и удаление элементов которого можно совершить только с одного конца – из вершины стека. Стек организован по принципу LIFO (Last Input First Output) – “последним вошел, первым вышел”. Стек, аналогично списку, состоит из связных узлов, каждый из которых представляет собой поле данных и указатель, содержащий адрес следующего элемента. Указатель последнего элемента имеет значение NULL, чтобы тем самым обозначить конец стека (рис. 9.5).
Рис. 9.5. Стек
Над стеком выполняются две основные операции: занести элемент данных в стек – функция PUSH, и извлечь элемент данных из вершины стека – функция POP.
Ниже приведено программное описание стека. Он содержит два поля: поле данных типа char и указатель на структуру того же типа, т.е. на следующий элемент стека.
struct Stack
{
char letter;
struct Stack *nextPtr;
};
Функция помещения элемента в стек, в качестве параметров получает указатель на первый элемент или нулевой указатель, если стек не создан, и переменную, которую необходимо поместить в стек. Далее происходит выделение динамической памяти для нового элемента. И этот элемент вставляется в начало стека путем присваивания указателю на следующий элемент указателя на начало стека, а указателю на начало стека, соответственно значения указателя на новый элемент.
typedef Stack *StackPtr;
void push(StackPtr *beginPtr, char value)
{
StackPtr newPtr;
//выделение памяти под элемент
newPtr = (Stack *) malloc(sizeof(Stack));
if (newPtr != NULL)
{
newPtr->letter = value;
newPtr->nextPtr = *beginPtr; // помещение элемента
*beginPtr = newPtr; // в стек
}
else
printf("Ошибка выделения памяти!!!");
}
Функция poр получает в качестве параметров указатель на начало стека, а возвращает значение, которое оттуда извлекает, т.е. элемент данных, который находился в вершине стека. Для удаления элемента рабочему указателю присваивается значения указателя на начало стека. В свою очередь, значению указателя на начало стека присваивается значение указателя на следующий элемент стека, а динамическая память выделенная под удаляемый элемент освобождается при помощи функции free.
char pop(StackPtr *beginPtr)
{
char popValue;
StackPtr tempPtr;
tempPtr = *beginPtr;
popValue = (*beginPtr)->letter; // присваивание значения
// возвращаемого элемента
// переопределение указателя на начало стека
*beginPtr = (*beginPtr)->NextPtr;
free(tempPtr); //освобождение памяти
return popValue;
}
При использовании стека в программе, следует очистить его, когда в нем уже не будет надобности, это сэкономит машинные ресурсы.