Поиск кратчайшего пути в лабиринте - Курсовая работа

бесплатно 0
4.5 64
Разработка и написание программы на языке Си для поиска кратчайшего пути в лабиринте. Эффективные алгоритмы нахождения кратчайшего пути на графе. Описание работы и функциональных возможностей программы. Методика и результаты тестирования программы.


Аннотация к работе
Полоцкий государственный университет Курсовая работа по курсу: “Конструирование программ и языки программирования” на тему: “Поиск кратчайшего пути в лабиринте”По мере того как время шло и алгоритмы усложнялись, программирование требовало все больше времени, а внесение изменений в программы и их модернизация становились практически невозможными. Все алгоритмы, применяемые для нахождения кратчайшего пути можно разделить на два типа: алгоритмы на графах и алгоритмы на массивах. Две точки будем называть соседними, если они имеют только одну различную координату (например, точки Map [5, 4] и Map [6, 4] - соседние, а точки Map [5, 4] и Map [6, 3] - нет). Требуется построить последовательность соседних элементов с нулевыми значениями такую, чтобы первым элементом в ней был Map [x_begin, y_begin], а последним - Map [x_end, y_end], причем число элементов в ней было бы минимальным из всех возможных. void CREATEMAP(int Length_Map,int Width_Map) - создает массив MAP, при чем если данный массив уже существовал, то происходит его удаление из памяти, а затем уже создается новый массив; в качестве параметров функция принимает целочисленные значения (размеры карты);Итак, в результате проделанной работы была разработана программа для поиска кратчайшего пути в лабиринте.

Введение
В начале компьютерной эры программисты были рабами вычислительных машин. Разработчики программного обеспечения должны были писать свои команды на единственном языке, который понимали компьютеры, - в двоичном коде, и программы выглядели как последовательность нулей и единиц. По мере того как время шло и алгоритмы усложнялись, программирование требовало все больше времени, а внесение изменений в программы и их модернизация становились практически невозможными. Так появились языки программирования высокого уровня: Фортран, Бейсик, Паскаль. Требования к программам росли, времени для их написания отводилось все меньше, программистам надо было сосредоточится на сложных алгоритмах, их эффективной реализации, не отвлекаясь на внутреннюю структуру компьютера. А тут еще проблемы переносимости программ на новые компьютеры с новыми возможностями. Был необходим новый подход - и он появился в виде объектно-ориентированного программирования.

В данной курсовой работе при написании программы был использован язык Си. Язык Си - это универсальный язык программирования, для которого характерны экономичность выражения, современный набор операторов и типов данных. Язык Си не является языком "очень высокого уровня" и не предназначается для некоторой специальной области применения, но отсутствие ограничений и общность языка делают его для многих задач более удобным и эффективным, чем языки, предположительно более мощные. Язык Си не связан с какими- либо определенными аппаратными средствами или системами, и на нем легко писать программы, которые можно пропускать без изменений на любой ЭВМ, имеющей Си-компилятор.

1. Постановка задачи

Задача данной курсовой работы состоит в разработке и написании программы на языке Си для поиска кратчайшего пути в лабиринте. Теория о нахождении кратчайших путей имеет весьма важное значение и широко применяется. Например, используется при нахождении оптимального маршрута между двумя объектами на местности, также используется в системах автопилота, используется для нахождения оптимального маршрута при перевозках коммутации информационного пакета Internet, при проектировании и построении плат и мн. др.

Все алгоритмы, применяемые для нахождения кратчайшего пути можно разделить на два типа: алгоритмы на графах и алгоритмы на массивах.

Итак, как было отмечено выше, задачу о нахождении кратчайшего пути можно рассматривать при помощи математического объекта, называемого графом. Граф задается множеством точек (вершин) и множеством линий (ребер), соединяющих все или часть этих точек.

Существуют три наиболее эффективных алгоритма нахождения кратчайшего пути на графе: 1) алгоритм Дейкстры. Используется для нахождения оптимального маршрута между двумя вершинами.

2) алгоритм Флойда. Используется для нахождения оптимального маршрута между всеми парами вершин.

3) алгоритм Йена. Используется для нахождения k-оптимальных маршрутов между двумя вершинами.

Самый распространенный пример подобных задач, это нахождение кратчайшего расстояния между двумя вершинами. В этом случае, весом дуги (хі, xj) будет являться расстояние между вершинами хі и xj, ну, а если такая дуга отсутствует, то ее вес полагается равным бесконечности (на практике - это максимальное число, возможное на данном языке программирования).

Наиболее эффективный алгоритм решения задачи о кратчайшем (s-t)-пути первоначально предложил Дейкстра (1959г.). В общем случае этот метод основан на приписывании вершинам временных пометок, причем пометка вершины дает верхнюю границу длины от s к этой вершине. Эти пометки (их величины) постепенно уменьшаются с помощью некоторой итерационной процедуры, и на каждом шаге итерации одна из временных пометок становится постоянной. Последнее указывает на то, что пометка уже не является временной, а дает точную длину кратчайшего пути от s к рассматриваемой вершине.

Только что описанный алгоритм Дейкстры применим для нахождения кратчайшего пути между двумя заданными вершинами s и t. Что бы найти кратчайшие пути между всеми парами вершин, можно n-раз воспользоваться алгоритмом Дейкстры, причем каждый раз в качестве начальной вершины s будут браться различные вершины. В этом случае время, необходимое для вычислений, будет пропорционально n3. Поэтому, если задача о нахождении кратчайшего пути имеет большую размерность, то ее не возможно решить с помощью последовательного применения этого алгоритма.

Есть совершенно иной подход к задаче нахождения кратчайших путей между всеми парами вершин. Он сэкономит почти 50% времени по сравнению с n-кратным применением алгоритма Дейкстры. Метод был предложен первоначально Флойдом (1962 г.) и развит Мерчлендом. Он базируется на использовании последовательности из n преобразований (итераций) начальной матрицы весов С. При этом на k-й итерации матрица представляет длины кратчайших путей между каждой парой вершин с тем ограничением, что путь между xi и xj (для любых xi и xj) содержит в качестве промежуточных только вершины из множества {x1, x2,..., xk}.

На практике часто требуется найти не только кратчайший путь, но также второй, третий и т. д. кратчайшие пути в графе. Располагая этими результатами, можно решить, какой путь выбрать в качестве наилучшего. Для решения этой задачи нужно воспользоваться алгоритмом Йена (1971г.). Этот алгоритм требует порядка Kn3 операций.

Существует тип алгоритмов, который в американской литературе фигурирует под названием backtracking algorithms, что в переводе означает “алгоритмы с откатом”. Как правило, такие алгоритмы строятся на основе рекурсии. Эти алгоритмы отличаются от других тем, что ищут решения методом проб и ошибок, перебирая все или почти все варианты.

Backtracking используется в тех случаях, когда более интеллектуальные решения невозможны. Количество таких задач ограничено. Например, поиск оптимума с полным перебором всех вариантов, поиск любого решения с выходом при его отыскании или поиск оптимального решения с оптимизацией полного перебора (отсечением вариантов, которые заведомо хуже ранее найденного оптимального решения). К такому методу относится волновой алгоритм.

Основная часть алгоритма - построение на основе массива множества точек, до которых можно добраться за К шагов и нельзя быстрее (этот процесс аналогичен процессу распространения волны, откуда и произошло название алгоритма).

В рамках рассмотрения задачи о поиске кратчайшего пути между двумя точками в лабиринте более целесообразным является использование волнового алгоритма. Его преимуществами являются: легкость переноса с карты лабиринта на массив, т.е. простота построения модели задачи, простота понимания самого алгоритма, быстродействие, а также то, что если пути нет, то это становится известным на определенном шаге и алгоритм дальше не выполняется.

2. Проектирование программы

Прежде всего построим модель задачи. Здесь мы должны решить, то означают слова: "карта лабиринта", "непроходимый участок", "кратчайший маршрут".

Всю карту можно представить в виде двухмерного целочисленного массива Map, индексы которого - координаты соответствующих точек, а значения - признак возможности прохождения точки с координатами х и у. Map [х, у] = 0, если участок проходим, и равно -1, если нет. Две точки будем называть соседними, если они имеют только одну различную координату (например, точки Map [5, 4] и Map [6, 4] - соседние, а точки Map [5, 4] и Map [6, 3] - нет). Маршрутом будем считать последовательность соседних точек карты. Длиной маршрута будем считать число клеток в нем.

В терминах этой модели исходная задача формулируется так: даны двухмерный числовой массив Map с элементами, равными 0 и -1, и две пары индексов (две точки): x_begin, y_begin и x_end, y_end. Требуется построить последовательность соседних элементов с нулевыми значениями такую, чтобы первым элементом в ней был Map [x_begin, y_begin], а последним - Map [x_end, y_end], причем число элементов в ней было бы минимальным из всех возможных.

Содержательное описание волнового алгоритма таково: 1. Начальный этап. Пометим начальную точку числом 1 (в эту точку ведет маршрут длины 0).

2. Распространение волны. Если рассматриваемая точка помечена числом К > 0 (в нее можно попасть за К-1 шагов), то все соседние точки, помеченные нулем, надо пометить числом К 1 (в них можно попасть за К шагов). Распространение волны осуществляется до тех пор, пока это возможно (есть еще соседние, помеченные нулем, точки) и целесообразно (еще не дошли до конечной точки).

3. Проверка возможности построения пути. Если после распространения волны конечная точка помечена некоторым числом К > 0, то в нее можно попасть за К- 1 шаг. В противном случае эта точка недостижима из начальной.

4. Построение пути. Для того чтобы построить оптимальный маршрут, необходимо, начиная с конечной точки, выбирать соседнюю с ней, помеченную числом на единицу меньше. Затем проделать это же с новой точкой. И так далее, пока не доберемся до начальной.

Из описания алгоритма видно, что он распадается на два этапа: распространение волны (включая начальный этап) и построение пути.

При разработке программы были реализованы следующие возможности: рисование произвольной карты, сохранение карты в файл и загрузка ее из файла, непосредственно поиск кратчайшего пути.

Для реализации данных возможностей были написаны следующие модули: GRAPHICA;

SHORTWAY;

MOUSE;

MAIN.

В модуле GRAPHICA содержатся функции рисования различных графических объектов.

В модуле SHORTWAY содержатся функции для нахождения пути, а также функции для работы с файлами и функции для создания и работы с меню программы.

В модуле MOUSE содержатся функции для работы с мышью.

Модуль MAIN является главным, потому что он содержит функцию MAIN и управляет работой всей программы.

В данной курсовой используются следующие типы данных: динамические массивы целых чисел MAP и WAY для хранения карты и пути;

динамический список для хранения имен файлов, в которые записываются карты.

Далее рассмотрим более подробно функции каждого модуля, их назначение при работе программы, установим связи между функциями и между самими модулями.

3. Реализация программы

3.1 Модуль GRAPHICA

Данный модуль содержит следующие функции: - void INITGRAPH() - инициализирует графический режим;

- int Size_of_Map(int &maxx,int &maxy) - рисует окно для введения размеров карты и возвращает эти размеры(int maxx,int maxy);

- void Draw_Menu() - рисует меню;

- void Draw_Map(int maxx,int maxy) - принимает в качестве параметров размеры карты(int maxx,int maxy) и рисует по ним “пустую” карту;

- int DRAWOBJECT(int &i) - в правом нижнем углу экрана отбражает текущий объект(block - стена; Start - начальная точка; Finish - конечная точка) и по нажатию правой клавиши мыши меняет объект, в качестве параметра принимает текущий номер объекта(0 - block; 1 - start; 2- finish) по ссылке, при необходимости меняет его и возвращает в момент вызова функции;

- void DRAWBLOCK(int maxx,int maxy) - рисует на карте по значениям массива MAP соответствующие объекты(-1 - стена; 0 - проход; 1 - S; 2 - F), принимает в качестве параметров размеры карты;

- int Menu() - реализует возможность перемещения по меню и по нажатию клавиши ENTER возвращает код выбранного значения(0 - DRAW; 1 - LOAD; 2 - SAVE; 3 - FIND; 4 - HELP; 5 - EXIT );

- void DRAWPATH(int maxx,int maxy,int x_end, int y_end) - по значениям массива WAY рисует на карте массив.

3.2 Модуль SHORTWAY

Данный модуль кроме функций (см. ниже) содержит также такие глобальные переменные как int **Way - двойной указатель на массив указателей одномерных массивов(массив пути), int **Map - массив карты.

Функции Move_Head(),Move_Next(),Move_Prev(),CREATEDATA(), Destroy(), Add() нужны для работы с динамическим списком, в котором хранятся имена файлов, хранящих карты.

- void Move_Head() - устанавливает текущий указатель на начало списка;

- void Move_Next() - перемещает указатель по списку вперед;

- void Move_Prev() - перемещает указатель по списку назад;

- void CREATEDATA() - считывает из файла BASEDAT.TXT в список имена файлов;

- void Destroy() - удаляет список из памяти, предворительно записав значения в файл BASEDAT.TXT;

- int Add(char str[12]) - добовляет в конец списка очередное значение, прочитанное либо из файла BASEDAT.TXT, либо введенное при сохранении карты в функции Save(); в качестве параметра функция принимает значение типа char(имя файла), а возвращает целочисленное значение(1 - если добавление произошло и 0 - в противном случае);

- void CREATEMAP(int Length_Map,int Width_Map) - создает массив MAP, при чем если данный массив уже существовал, то происходит его удаление из памяти, а затем уже создается новый массив; в качестве параметров функция принимает целочисленные значения (размеры карты);

- void Restore_Map(int maxx,int maxy) - возобнавляет карту(массив MAP) после распространения волны; в качестве параметров принимает размеры карты;

- void ADDMAP(int i,int j) - по нажатию левой клавиши мыши и при выбранном объекте Block добавляет в массив MAP -1 по соответствующим координатам; в качестве параметров принимает координаты стены;

- int Save(int maxx,int maxy) - сохраняет в файле карту; в качестве параметров принимает размеры карты, которые тоже записываются в этот же файл (это нужно для загрузки карты из файла);

int GETSTRING(char *str, int x,int y) - позволяет прочитать строку (имя файла) при ее вводе, а также производит проверку на правильность ввода имени файла; в качестве параметров принимает координаты, по которым будет производится ввод строки, возвращает строку, а также значение целого типа (-1 - произошел выход из функции по ESC без считования в строку, 0 - ошибка в имени файла, 1 - произошло считование строки);

- void Load(int &maxx,int &maxy) - производит загрузку из файла карты, возвращая по ссылке размеры карты;

- int SHORTWAY(int Length_Map,int Width_Map,int x_begin,int y_begin,int x_end,int y_end) - производит формирование массива WAY, принимая в качестве параметров размеры карты и кординаты начальной и конечной точек; возвращает 0 - если построение пути невозможно, в противном случае возвращает длину пути;

- void Wave(int x_begin,int y_begin,int x_end,int y_end,int Length_Map,int Width_Map) - функция распространения волны, в качестве параметров принимает конечной и начальной точек, а также размеры карты;

- void Way_Step(int x,int y,int step) - присоединяет очередную точку к маршруту, принимая в качестве параметров кординаты точки и шаг;

- void Track(int x_end,int y_end) - функция построения пути использует заполненный массив MAP и на его основе формирует массив WAY, начиная от конечной точки, принимает в качестве параметров координаты конечной точки.

3.3 Модуль MOUSE

Данный модуль содержит следующие функции: - void MOUSECLOSE() - данная функция “гасит” мышь на экране;

- void INITMOUSE() - инициализирует мышь;

- int MOUSEHIT(int &x,int &y) - возвращает код нажатой клавиши мыши (0 - никакая клавиша не нажата, 1 - нажата левая клавиша, 2 - нажата правая клавиша), а также по ссылке возвращает координаты мыши.

3.4 Описание работы программы

Теперь опишем работу всей программы, графическое отображение которой представлено в схеме модулей (Приложение А) и схеме вызова функций (Приложение Б).

В модуле MAIN включены все остальные модули, а сам модуль содержит только функцию main. Поэтому описание работы программы начнем с описания функции main.

Итак, вначале инициализируем графический режим с помощью функции INITGRAPH, отрисовываем меню(Draw_Menu), создаем список Basedat для хранения имен файлов, отрисовываем объект(по умолчанию Block) c помощью функции DRAWOBJECT, инициализируем мышь.

Затем входим в цикл, выходом из которого является выбор в меню кнопки EXIT. Для входа в меню нажимаем F10. Если в меню выбираем DRAW, то выполняем следующий блок: гасим мышь(MOUSECLOSE), считываем размеры карты(Size_of_Map), отрисовывем меню(DRAWMENU), отрисовываем объект(DRAWOBJECT), создаем карту(CREATEMAP) и отрисовываем ее(DRAWMENU), инициализируем мышь(INITMOUSE). Если в меню выбираем LOAD, то выпоняется следующий блок: гасим мышь(MOUSECLOSE), загружаем карту(Load), инициализируем мышь (INITMOUSE). Если в меню выбираем SAVE, то выполяется блок, в результате которого происходит сохранение карты в файл (основная функция - Save). Если в меню выбираем FIND, то выполняется блок, в котором получаем путь или собщение о том, что путь не существут(главная функция - SHORTWAY). Кроме работы с меню в главном цикле осуществляется считывание и анализ нажатой клавиши мыши (MOSEHIT). Если нажата левая клавиша, то в массив Map заносится определенное значение(ADDMAP), по которому затем на карте по сответсвующим координатам рисуется текущий объект(DRAWBLOCK). Нажатие правой клавиши мыши позволяет сменить объект рисования.

Для организации такой работы программы необходимо, чтобы в модуле MAIN были включены остальные модули(MOUSE, SHORTWAY, GRAPHICA). Модуль MAUSE включен также в модуль GRAPHICA, а модули GHORTWAY и GRAPHICA включены друг в друга. Включение функций можно проследить по схеме вызова функций (Приложение Б).

4. Методика и результаты тестирования

При создании и отладке программы были произведены следующие тесты и получены следующие результаты.

TEST 1 программа лабиринт алгоритм тестирование

Таблица 1

Массив МАР

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14

0 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1

1 -1 0 -1 0 0 0 0 0 0 0 0 0 -1 -1 -1

2 -1 0 -1 0 0 -1 0 0 -1 -1 0 0 -1 0 -1

3 -1 0 -1 -1 0 -1 0 0 0 -1 0 0 -1 0 -1

4 -1 0 0 0 0 -1 -1 0 0 -1 0 0 -1 0 -1

5 -1 0 0 0 -1 -1 0 0 -1 -1 0 0 -1 0 -1

6 -1 0 0 0 0 0 0 0 0 0 0 0 0 0 -1

7 -1 0 -1 0 -1 -1 -1 -1 -1 -1 -1 0 0 0 -1

8 -1 0 -1 0 0 0 0 0 0 0 -1 0 -1 0 -1

9 -1 0 -1 0 -1 0 -1 -1 0 0 -1 0 0 0 -1

10 -1 0 -1 0 0 -1 -1 -1 -1 0 -1 0 -1 0 -1

11 -1 0 -1 0 0 0 0 0 0 0 0 0 -1 -1 -1

12 -1 0 -1 -1 0 -1 -1 0 -1 -1 0 -1 -1 0 -1

13 -1 0 0 0 0 -1 -1 0 0 0 0 0 0 0 -1

14 -1 0 -1 -1 0 0 -1 -1 -1 -1 0 0 0 0 -1

15 -1 0 -1 -1 -1 0 0 0 0 0 0 -1 -1 -1 -1

16 -1 0 -1 -1 -1 -1 -1 0 -1 -1 0 -1 0 0 -1

17 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1

MAP[7][13] ->MAP[1][1]

Таблица 2

Массив МАР после распространения волны

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14

0 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1

1 -1 19 -1 19 18 19 0 0 0 19 18 17 -1 -1 -1

2 -1 18 -1 18 17 -1 0 0 -1 -1 17 16 -1 18 -1

3 -1 17 -1 -1 16 -1 0 19 0 -1 16 15 -1 17 -1

4 -1 16 15 14 15 -1 -1 18 19 -1 15 14 -1 16 -1

5 -1 15 14 13 -1 -1 16 17 -1 -1 14 13 -1 15 -1

6 -1 14 13 12 13 14 15 16 15 14 13 12 13 14 -1

7 -1 15 -1 11 -1 -1 -1 -1 -1 -1 -1 11 12 13 -1

8 -1 16 -1 10 11 12 11 10 9 8 -1 10 -1 12 -1

9 -1 15 -1 9 -1 13 -1 -1 8 7 -1 9 10 11 -1

10 -1 14 -1 8 7 -1 -1 -1 -1 6 -1 8 -1 12 -1

11 -1 13 -1 7 6 5 4 3 4 5 6 7 -1 -1 -1

12 -1 12 -1 -1 7 -1 -1 2 -1 -1 5 -1 -1 8 -1

13 -1 11 10 9 8 -1 -1 1 2 3 4 5 6 7 -1

14 -1 12 -1 -1 9 10 -1 -1 -1 -1 5 6 7 8 -1

15 -1 13 -1 -1 -1 11 10 9 8 7 6 -1 -1 -1 -1

16 -1 14 -1 -1 -1 -1 -1 10 -1 -1 7 -1 0 0 -1

17 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1

Таблица 3

Массив WAY

0 1

0 1 1

1 2 1

2 3 1

3 4 1

4 5 1

5 6 1

6 6 2

7 6 3

8 7 3

9 8 3

10 9 3

11 10 3

12 11 3

13 11 4

14 11 5

15 11 6

16 11 7

17 12 7

18 13 7

TEST 2

Таблица 4

Массив МАР

0 1 2 3 4 5 6 7 8 9 10

0 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1

1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1

2 -1 0 0 0 0 0 0 0 0 -1 -1

3 -1 -1 -1 -1 -1 -1 -1 -1 0 -1 -1

4 -1 -1 -1 0 0 0 0 -1 0 -1 -1

5 -1 -1 -1 0 -1 -1 0 -1 0 -1 -1

6 -1 -1 -1 0 0 0 0 -1 0 -1 -1

7 -1 -1 -1 0 -1 -1 -1 -1 0 -1 -1

8 -1 -1 -1 0 0 0 0 0 0 -1 -1

9 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1

10 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1

MAP[1][2]->MAP[5][6]

Таблица 5

Массив МАР после распространения волны

0 1 2 3 4 5 6 7 8 9 10

0 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1

1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1

2 -1 1 2 3 4 5 6 7 8 -1 -1

3 -1 -1 -1 -1 -1 -1 -1 -1 9 -1 -1

4 -1 -1 -1 23 24 25 26 -1 10 -1 -1

5 -1 -1 -1 22 -1 -1 27 -1 11 -1 -1

6 -1 -1 -1 21 -1 29 28 -1 12 -1 -1

7 -1 -1 -1 20 -1 -1 -1 -1 13 -1 -1

8 -1 -1 -1 19 18 17 16 15 14 -1 -1

9 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1

10 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1

Таблица 6

Массив WAY

0 1

0 6 5

1 6 6

2 5 6

3 5 6

4 4 5

5 4 4

6 4 3

7 5 3

8 6 3

9 7 3

10 8 3

11 8 4

12 8 5

13 8 6

14 8 7

15 8 8

16 7 8

17 6 8

18 5 8

19 4 8

20 3 8

21 2 8

22 2 7

23 2 6

24 2 5

25 2 4

26 2 3

27 2 2

28 2 1

Вывод
Итак, в результате проделанной работы была разработана программа для поиска кратчайшего пути в лабиринте. Для решения данной задачи был использован волновой алгоритм. Для демонстрации работы программы разработан графический интерфейс, реализованы такие возможности как загрузка и сохранение карты в файле, редактирование карты.

Список литературы
1. Карпов Б., Баранова Т. С :специальный справочник. СПБ: Питер, 2001.

2. Болсии М.И. Язык программирования Си. М.: Радио и связь, 1988.

3. Керниган Б., Ритчи Д., Фьюкор А. Язык программирования Си. Задачи по языку Си. М.: Финансы и статистика, 1985, 1992.

4. Хэнкок Л., Кригер М. Введение в программирование на языке Си. М.: Радио и связь, 1986. 4. Уэйт М., Прата С., Мартин Д. Язык Си. М.: Мир, 1988.
Заказать написание новой работы



Дисциплины научных работ



Хотите, перезвоним вам?