- •Тема 1. Алгоритмы и программы 4
- •Тема 2. Характеристика языка Си 6
- •Тема 3. Основы языка Си 11
- •Тема 4.Работа с файлами 33
- •Тема 5.Распределение памяти 40
- •Тема 6. Методы организации данных в памяти эвм 43
- •Тема 7. Некоторые алгоритмы обработки данных 58
- •Тема 1. Алгоритмы и программы Цели и задачи изучения темы
- •1.1.Понятие алгоритма. Понятие программы. Способы записи алгоритмов.
- •1.2.Критерии качества программ
- •1.3.Низкоуровневые и высокоуровневые языки программирования
- •1.4.Принципы структурного программирования
- •Принципы структурного программирования.
- •2.2.Основные характеристики языка Си.
- •2.2.1.Достоинства языка Си
- •2.2.2.Компиляторы и интерпретаторы
- •2.2.3.Сильная типизация
- •2.3.Структура простой программы
- •Вопросы для повторения
- •3.1.2.Основные типы данных
- •3.1.3.Структуры данных
- •3.1.4.Оператор определения имени типа typedef
- •3.1.5.Массивы
- •3.1.6.Указатели
- •3.1.7.Указатели и массивы
- •3.1.8.Внешние и внутренние переменные
- •3.2.Стандартные функции ввода-вывода
- •3.3. Операции, операторы и выражения
- •3.3.1.Оператор присваивания
- •3.3.2.Арифметические операции
- •3.3.3.Операции увеличения и уменьшения
- •3.3.4.Операции сравнения
- •3.3.5.Логические операции
- •3.3.6.Побитовые логические операции
- •3.3.7.Операции сдвига
- •3.3.8.Операции "увеличить на", "домножить на" и т.П.
- •3.3.9.Операции с указателями. Указатели и массивы
- •3.3.10.Операция приведения типа
- •3.4.Управляющие конструкции
- •3.4.1.Фигурные скобки
- •3.4.2.Оператор выбора if и операция условия
- •3.4.3.Оператор множественного выбора switch
- •3.4.4.Оператор цикла while
- •3.4.5.Оператор цикла for
- •3.4.6.Оператор цикла do...While
- •3.5.Данные (более детальные сведения)
- •3.5.1.Структуры
- •3.5.2.Указатели и структуры
- •3.5.3.Структуры и оператор определения имени типа typedef
- •3.5.4.Строки
- •3.5.5.Матрицы и многомерные массивы
- •3.6.Пользовательские функции
- •3.6.1.Определение функций
- •3.6.2.Прототипы функций
- •3.6.3.Аргументы командной строки
- •Вопросы для повторения
- •4.2.Функция открытия файла fopen
- •4.3.Функции бинарного чтения и записи fread и fwrite
- •4.4.Функция закрытия файла fclose
- •4.5.Функции форматного чтения и записи fscanf и fprintf
- •4.6.Другие функции ввода-вывода
- •4.6.1.Функции посимвольного ввода-вывода
- •Int fgetc(file *f); - ввести один символ из файла f.
- •Int fputc(int c, file *f); - записать один символ в файл f.
- •4.6.2.Функции построкового ввода-вывода
- •Char *fgets(char *line,int size, file *f); - ввести строку из файла f.
- •Char *fputs(char *line, file *f); - записать строку в файл f.
- •4.6.3.Функции позиционирования в файле
- •Int fseek(file *f, long offset, int whence); - установить текущую позицию в файле f
- •Long ftell(file *f); - получить текущую позицию в файле f
- •Int feof(file *f); - проверить,достигнут ли конец файла f
- •Функция открытия файла fopen
- •Функции бинарного чтения и записи fread и fwrite
- •Функция закрытия файла fclose
- •5.2.Функции malloc и free
- •5.3.Выделение памяти под матрицы на этапе выполнения программы
- •Функции malloc и free.
- •6.2.Время выполнения программ
- •6.3.Списки
- •6.4.Реализация списков
- •6.5.Стеки
- •6.6.Реализация стеков
- •6.7.Очереди
- •6.8.Реализация очередей
- •6.9.Графы и деревья
- •6.10.Некоторые сд для хранения графов и деревьев
- •Матрица смежности графа, изображенного на рис.6.10
- •Матрица инцидентности графа, изображенного на рис.6.10
- •Матрица весов графа, изображенного на рис.6.11
- •Матрица смежности дерева, изображенного на рис.6.16
- •Вопросы для повторения
- •Реализация стеков.
- •Реализация очередей.
- •7.1.1.Поиск элемента в неупорядоченном массиве
- •7.1.2.Поиск элемента в упорядоченном массиве.
- •7.1.3.Фонетический поиск
- •7.2.Алгоритмы сортировки
- •7.2.1.Сортировка методом пузырька.
- •7.2.2.Сортировка вставками
- •7.2.3.Сортировка выбором
- •7.2.4.Пирамидальная сортировка
- •7.2.5.Быстрая сортировка
- •7.2.6.Сортировка слиянием
- •Этапы слияния файлов f1 и f2
- •7.3.Поиск на графах
- •7.3.1.Поиск в глубину
- •7.3.2.Поиск в ширину
- •7.4.Топологическая сортировка графа
- •7.5.Сетевое планирование
- •Информация о проекте
- •7.5.1.Алгоритм расчета наиболее ранних сроков наступления событий
- •7.5.2.Алгоритм расчета наиболее поздних сроков наступления событий
- •7.5.3.Алгоритм расчета резервов времени
- •Расчет резервов времени
- •Вопросы для повторения
5.3.Выделение памяти под матрицы на этапе выполнения программы
Пусть нужна матрица, размер которой определяется во время работы программы. Можно предложить два способа решения этой задачи. Первый способ основан на использовании одномерного массива для хранения элементов матрицы. Выделение памяти для такого массива можно выполнить с помощью функции malloc:
double *a;
. . .
a = (double *) malloc(m * n * sizeof(double));
При этом считается, что элементы матрицы будут располагаться в массиве следующим образом: сначала идут элементы строки с индексом 0, затем элементы строки с индексом 1 и т.д., последними идут элементы строки с индексом m − 1. Каждая строка состоит из n элементов, следовательно, индекс элемента строки i и столбца j в линейном массиве равен
i * n + j
Таким образом, элементу матрицы в строке i и столбце j соответствует выражение
a[i * n + j]
Для освобождения памяти, занимаемой матрицей можно использовать функцию free:
free(a);
Основное преимущество такого способа представления матрицы состоит в том, что элементы матрицы хранятся в непрерывном отрезке памяти, что повышает скорость доступа к элементу.
Также матрицу можно реализовать как массив указателей на ее строки, при этом память под каждую строку захватывается отдельно:
double **a; // Адрес массива указателей
int m, n; // Размеры матрицы: m строк, n столбцов
int i;
. . .
// Захватывается память под массив указателей
a = (double **) malloc(m * sizeof(double *));
for (i = 0; i < m; ++i) {
// Выделяем память под строку с индексом i
a[i] = (double *) malloc(n * sizeof(double));
}
После этого к элементу a ij можно обращаться с помощью выражения
a[i][j]
Преимущество такого способа только в использовании привычного синтаксиса для обращения к элементу матрицы. Недостаток в том, что матрица не хранится в непрерывном участке памяти, что снижает скорость доступа к элементу. Кроме того, при таком способе хранения матрицы требуется дополнительная память для хранения указателей на строки матрицы. Также к недостаткам данного способа можно отнести более длинный код для выделения памяти и для освобождения памяти. Для освобождения памяти будет использоваться следующий код:
for (i = 0; i < m; ++i) free(a[i]);
free(a);
Для выделения памяти под многомерные массивы лучше использовать способ, аналогичный первому способу. Например, пусть надо реализовать трехмерный вещественный массив размера m × n × k. Выделяем линейный массив вещественных чисел размером m * n * k:
double *a;
. . .
a = (double *) malloc(m * n * k * sizeof(double));
Доступ к элементу с индексами x, y, z осуществляется с помощью выражения
a[(x * n + y) * k + z].
Вопросы для повторения
Вопросы выделение памяти на этапе компиляции и на этапе выполнения программы
Функции malloc и free.
Способы выделения памяти под матрицы на этапе выполнения программы. Преимущества и недостатки различных способов.
Выделение памяти под многомерные массивы на этапе выполнения программы.
Резюме по теме
В данной теме рассмотрены основные средства языка Си и приемы выделения и освобождения памяти на этапе выполнения программы.
Тема 6. Методы организации данных в памяти ЭВМ
Цели и задачи изучения темы
В данной теме рассматриваются различные методы организации данных в памяти ЭВМ.
6.1.Абстрактные типы данных
Абстрактный тип данных (АТД) — это математическая модель плюс различные операторы, определенные в рамках этой модели. Мы можем разрабатывать алгоритм в терминах АТД, но для реализации алгоритма в конкретном языке программирования необходимо найти способ представления АТД в терминах типов данных и операторов, поддерживаемых данным языком программирования.
Для представления АТД используются структуры данных, которые представляют собой набор переменных, возможно, различных типов данных, объединенных определенным образом.