Студопедия
Случайная страница | ТОМ-1 | ТОМ-2 | ТОМ-3
АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатика
ИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханика
ОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторика
СоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансы
ХимияЧерчениеЭкологияЭкономикаЭлектроника

Программная документация.

Читайте также:
  1. В разделе программная и техническая архитектура ИС предприятия
  2. Исполнительная документация.
  3. Тема 4: Патентная информация и документация.

Пожалуй, самым неприятным и тяжелым этапом программистской работы является создание программной документации.

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

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

Создание Программной документации:

Для начала необходимо вооружиться ГОСТами. В частности, в них входит Единая система программной документации (ЕСПД). Никаких цитат и вторичных источников использовать нельзя. ГОСТ – это закон.

Единая система программной документации – это комплекс государственных стандартов, устанавливающих взаимоувязанные правила разработки, оформления и обращения программ и программной документации.

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

• основополагающие и организационно-методические стандарты;

• стандарты, определяющие формы и содержание программных документов, применяемых при обработке данных;

• стандарты, обеспечивающие автоматизацию разработки программных документов.

Перечень документов ЕСПД очень обширен.

Основная часть комплекса ЕСПД была разработана в 70-е и 80-е годы. Частично эти стандартны морально устарели, к тому же они не лишены некоторых недостатков. Во-первых, в них не отражены некоторые современные тенденции оформления программ и программной документации, во-вторых, в этих стандартах наличествует многократное дублирование фрагментов программной документации.

Стандарты ЕСПД упорядочивают процесс документирования программных систем. Однако, во-первых, предусмотренный стандартами ЕСПД состав программных документов вовсе не такой "жесткий", как может показаться: стандарты позволяют вносить в комплект документации на программной системы (ПС) дополнительные виды, а, во-вторых, исходя из требований заказчика, допустимы некоторые изменения как в структуре, так и в содержании установленных видов ПД. Более того, можно отметить, что стандарты ЕСПД (а это относится и ко всем другим стандартам в области ПС - ГОСТ 34, Международному стандарту ISO/IEC, и др.) носят рекомендательный характер. Дело в том, что в соответствии с Законом РФ "О стандартизации" эти стандарты становятся обязательными на контрактной основе – т.е. при ссылке на них в договоре на разработку (поставку) ПС.

 

35. Технология структурного и объектно-ориентированного программирования Объектно-ориентированное программирование (ООП) определяется как технология создания сложного программного обеспечения, основанная на представлении программы в виде совокупности объектов, каждый из которых является экземпляром определенного типа (класса), а классы образуют иерархию с наследованием свойств. Взаимодействие программных объектов в такой системе осуществляется путем передачи сообщений. Основным достоинством объектно-ориентированного программирования по сравнению с модульным программированием является "более естественная" декомпозиция программного обеспечения, которая существенно облегчает его разработку. Это приводит к более полной локализации данных и интегрированию их с подпрограммами обработки, что позволяет вести практически независимую разработку отдельных частей (объектов) программы. Кроме этого, объектный подход предлагает новые способы организации программ, основанные на механизмах наследования, полиморфизма, композиции, наполнения. Эти механизмы позволяют конструировать сложные объекты из сравнительно простых. В результате существенно увеличивается показатель повторного использования кодов и появляется возможность создания библиотек классов для различных применений.Можно дать обобщающее определение: объект ООП — это совокупность переменных состояния и связанных с ними методов (операций). Упомянутые методы определяют, как объект взаимодействует с окружающим миром. Под методами объекта понимают процедуры и функции, объявление которых включено в описание объекта и которые выполняют действия. Возможность управлять состояниями объекта посредством вызова методов в итоге и определяет поведение объекта. Эту совокупность методов часто называют интерфейсом объекта. 36. Жизненный цикл ПО. Виды процессов проектирования ПО. Жизненный цикл ПО — период времени, который начинается с момента принятия решения о необходимости создания программного продукта и заканчивается в момент его полного изъятия из эксплуатации. Этот цикл — процесс построения и развития ПО.Основные Процессы жизненного цикла ПО:-Приобретение (действия и задачи заказчика, приобретающего ПО)-Поставка (действия и задачи поставщика, который снабжает заказчика программным продуктом или услугой)-Разработка (действия и задачи, выполняемые разработчиком: создание ПО, оформление проектной и эксплуатационной документации, подготовка тестовых и учебных материалов и т. д.)-Эксплуатация (действия и задачи оператора — организации, эксплуатирующей систему)-Сопровождение (действия и задачи, выполняемые сопровождающей организацией, то есть службой сопровождения). Сопровождение — внесений изменений в ПО в целях исправления ошибок, повышения производительности или адаптации к изменившимся условиям работы или требованиям.Модели жизненного цикла ПО:1.Водопадная (каскадная, последовательная) модель Преимущества: -Полная и согласованная документация на каждом этапе; -Легко определить сроки и затраты на проект.2. Итерационная модель3. Спиральная модель 37. Структурное и модульное программирование. Основные понятия. Сутью структурного программирования является возможность разбиения программы на составляющие элементы. Распространены две методики (стратегии) разработки программ, относящиеся к структурному программированию: программирование "сверху вниз" и программирование "снизу вверх".Достоинства структурного программирования:1) повышается надежность программ (благодаря хорошему структурированию при проектировании, программа легко поддается тестированию и не создает проблем при отладке);2) повышается эффективность программ (структурирование программы позволяет легко находить и корректировать ошибки, а отдельные подпрограммы можно переделывать (модифицировать) независимо от других);3) уменьшается время и стоимость программной разработки;4) улучшается читабельность программ.Модульное программирование - это организация программы как совокупности небольших независимых блоков (модулей), структура и поведение которых подчиняется определенным заранее правилам.Модулем (в модульном программировании) называется множество взаимосвязанных подпрограмм (процедур) вместе с данными, которые эти подпрограммы обрабатывают.Модульное программирование предназначено для разработки больших программ. 38. Основные понятия теории формальных языков Формальная грамматика или просто грамматика в теории формальных языков — способ описания формального языка, то есть выделения некоторого подмножества из множества всех слов некоторого конечного алфавита. Различают порождающие и распознающие (или аналитические) грамматики — первые задают правила, с помощью которых можно построить любое слово языка, а вторые позволяют по данному слову определить, входит оно в язык или нет.Терминал (терминальный символ) — объект, непосредственно присутствующий в словах языка, соответствующего грамматике, и имеющий конкретное, неизменяемое значение (обобщение понятия «буквы»). В формальных языках, используемых на компьютере, в качестве терминалов обычно берут все или часть стандартных символов ASCII — латинские буквы, цифры и спец. символы.Нетерминал (нетерминальный символ) — объект, обозначающий какую-либо сущность языка (например: формула, арифметическое выражение, команда) и не имеющий конкретного символьного значения.Выводом называется последовательность строк, состоящих из терминалов и нетерминалов, где первой идет строка, состоящая из одного стартового нетерминала, а каждая последующая строка получена из предыдущей путем замены некоторой подстроки по одному (любому) из правил. Конечной строкой является строка, полностью состоящая из терминалов, и следовательно являющаяся словом языка.Существование вывода для некоторого слова является критерием его принадлежности к языку, определяемому данной грамматикой.Типы грамматикПо иерархии Хомского, грамматики делятся на 4 типа, каждый последующий является более ограниченным подмножеством предыдущего (но и легче поддающимся анализу):тип 0. неограниченные грамматики — возможны любые правилатип 1. контекстно-зависимые грамматики — левая часть может содержать один нетерминал, окруженный «контекстом» (последовательности символов, в том же виде присутствующие в правой части); сам нетерминал заменяется непустой последовательностью символов в правой части.тип 2. контекстно-свободные грамматики — левая часть состоит из одного нетерминала.тип 3. регулярные грамматики — более простые, эквивалентны конечным автоматам. 39. Классификация языков и грамматик по Хомскому Иерархия Хомского — классификация формальных языков и формальных грамматик, согласно которой они делятся на 4 типа по их условной сложности. Предложена профессором Массачусетского технологического института, лингвистом Ноамом Хомским.Грамматика типа 0 - генеративная, самая сложная, никаких ограничений на вид ее правил не накладывается. Грамматика типа 0, порождающая (generative grammar), - в классической записи это четверка G=(N,∑, P, S), где N, ∑ - алфавит (N - нетерминальные символы, ∑ - терминальные символы метаязыка); S - начальный символ нетерминального множества, Р - правила репродукции (rewriting rules). Для распознавания языков, порождаемых этими грамматиками, используются машины Тьюринга - мощные, абстрактные, и следовательно неприменимые на практике математические модели, которые используются в теории информатики. Терминал (терминальный символ) — объект, непосредственно присутствующий в словах языка, соответствующего грамматике, и имеющий конкретное, неизменяемое значение (обобщение понятия «буквы»). В формальных языках, используемых на компьютере, в качестве терминалов обычно берут все или часть стандартных символов ASCII — латинские буквы, цифры и спец. символы. Нетерминал (нетерминальный символ) — объект, обозначающий какую-либо сущность языка (например: формула, арифметическое выражение, команда) и не имеющий конкретного символьного значения. Грамматика типа 1 - называют контекстно-зависимыми грамматиками, и в них возможность замены цепочки символов может определяться контекстом. Используются для генерации элементов естественных языков и подъязыков. Могут использоваться при анализе текстов на естественных языках, однако при построении компиляторов практически не используются в силу своей сложности. Грамматика типа 2 - контекстно-свободные, причем в левой части нетерминала могут быть всем, чем угодно. Они распознаются в информатике так называемыми автоматами с магазинной памятью (стековые автоматы). Используются для генерации элементов языков программирования (выражений, команд).Грамматика типа 3 - называют регулярными, самые простые и ограниченные грамматики, распознаются конечными автоматами. Используется для простых элементов языков (числа, константы, переменные). Применяются для описания простейших конструкций: идентификаторов, строк, констант, а также языков ассемблера, командных процессоров и др. 40. Синтаксис языка программирования. Общие синтаксические критерии. Синтаксис — сторона языка программирования, которая описывает структуру программ как наборов символов (обычно говорят — безотносительно к содержанию). Синтаксису языка противопоставляется его семантика. Синтаксис языка описывает «чистый» язык, в то же время семантика приписывает значения (действия) различным синтаксическим конструкциям.Каждый язык программирования имеет синтаксическое описание. Обычно синтаксис языка определяют посредством правил Бэкуса-Наура.Чаще всего синтаксис проверяется на ранних стадиях компиляции. В интерпретируемых языках программирования проверка синтаксиса производится или в процессе интерпретации (выполнения), или в процессе предварительной компиляции в промежуточный код. Кроме того синтаксис может проверяться непосредственно при редактировании исходных текстов программ при использовании IDE.Синтаксис записи функции — жёсткое правило, которому должна удовлетворять запись кода функции; форма записи функции. Если синтаксис функции будет неверен, компилятор возвратит ошибку и программа не будет собрана, пока ошибка не будет исправлена.К синтаксическим ошибкам записи функции относятся (неправильная сигнатура):• неверное написание названия функции при её вызове (неверный регистр символов для регистрострогих языков, неверное пространство имен);• неверное количество аргументов;• неверный тип переданных аргументов (например, нужно передать строковое значение, а передано числовое);• неверный тип возвращаемого значения (в частности, неуказанный тип). Форма Бэкуса—Наура (сокр. БНФ, Бэкуса—Наура форма) — формальная система описания синтаксиса, в которой одни синтаксические категории последовательно определяются через другие категории. БНФ используется для описания контекстно-свободных формальных грамматик.Используется для описания синтаксиса языков программирования, данных, протоколов (например, в документах RFC) и т. д. (причем как грамматики, так и регулярной лексики, поскольку регулярные грамматики являются подмножеством контекстно-свободных).БНФ-конструкция определяет конечное число символов (нетерминалов). Кроме того, она определяет правила замены символа на какую-то последовательность букв (терминалов) и символов. Процесс получения цепочки букв, можно определить поэтапно: изначально имеется один символ (символы обычно заключаются в угловые скобки, а их название не несёт никакой информации). Затем этот символ заменяется на некоторую последовательность букв и символов, согласно одному из правил. Затем процесс повторяется (на каждом шаге один из символов заменяется на последовательность, согласно правилу). В конце концов, получается цепочка, состоящая из букв и не содержащая символов. Это означает, что полученная цепочка может быть выведена из начального символа.БНФ-конструкция состоит из нескольких предложений вида <определяемый символ>::= <посл.1> | <посл.2> |... | <посл.n>, описывающих правила. Такое правило означает, что символ <определяемый символ> может заменяться на одну из последовательностей посл.1. Знак определения обычно выглядит как::= или →, но возможны и другие варианты.Некоторые специальные символы, как например <пусто>, означают какую-то последовательность (в данном случае — пустую).Примеры конструкций• Вот пример БНФ-конструкции, описывающей правильные скобочные последовательности: <правпосл>::=<пусто> | (<правпосл>) | <правпосл><правпосл>Это простая конструкция, состоящая всего из одного правила, утверждающего, что символ <правпосл> может замениться либо на пустое место, либо на этот же символ <правпосл>, заключённый в скобки, либо на два символа <правпосл> идущих подряд.Вот как получить с помощью этой конструкции цепочку ((())())() (ниже перечисляются все этапы, символы <пусто> опускаются):<правпосл><правпосл><правпосл>(<правпосл>)<правпосл>(<правпосл>)(<правпосл>)(<правпосл>)(<пусто>)(<правпосл><правпосл>)()((<правпосл>)<правпосл>)()((<правпосл>)(<правпосл>))() ((<правпосл>)(<пусто>))() (((<правпосл>))())() (((<пусто>))())() ((())())() 41. Синтаксические элементы языка.

Элементы синтаксиса языка, какого языка? Вот пример элементов языка bc

Комментарий до конца строки #
Комментарии, которые не могут быть вложенными /*... */
Регулярное выражение идентификатора переменной [a-z][_a-z0-9]*
Присваивание значения переменной =
Объявление переменной variable
Объявление переменной с присваиванием значения variable = value
Блок {... }
Равенство ==
Неравенство !=
Сравнение < > <= >=
Определение функции define f(p1, p2,...)...
Вызов функции f(a, b,...)
Вызов функции без параметров f()
Если - то if (condition)...
Если - то - иначе if (condition)... else...
Бесконечный цикл while (1)...
Цикл с предусловием while (condition)...
Цикл for - next для диапазона целых чисел с инкрементом на 1 for (i = 1; i <= 10; i++)...
Цикл for - next для диапазона целых чисел с декрементом на 1 for (i = 10; i > 0; i--)...
42. Общая структура программы-подпрограммы. Подпрограмма - обособленная именованная часть программы со своим собственным локальным контекстом имён. Или иначе: часть программы, оформленная в виде отдельной синтаксической конструкции и снабжённая именем. Вызов подпрограммы осуществляется по имени. Локальные объекты (константы, переменные, типы, подпрограммы) доступны только внутри подпрограммы. В Паскале подпрограммы бывают двух типов: процедуры и функции. Подпрограммы очень часто используются в программировании. По-другому их называют процедурами или функциями. Пока мы не будем усложнять себе жизнь и ограничимся использованием слова «подпрограмма». Что же это такое?Судя по названию, подпрограмма — это то, что входит в обычную программу (в программный код, который мы пишем). Что такое обычная программа? Это последовательность команд, в результате выполнения которой исполнителем (в нашем случае, черепахой) что-то происходит. Когда программа готова, нам достаточно нажать одну кнопку, чтобы ее запустить. А теперь представьте, что у нас в программе есть маленькие программки (подпрограммы), которые мы также запускаем нажатием всего лишь одной кнопки, после чего что-то происходит. Хотя на самом деле, никакой кнопки нет. Подпрограмма внутри программы запускается оттого, что ее вызывают по имени. Все это можно изобразить так:Здесь пунктирными линиями обозначены строки программного кода. Подпрограмм и их вызовов может быть много. Вызывается подпрограмма по ее имени.Подпрограммы изначально появились как средство оптимизации программ по объёму занимаемой памяти — они позволили не повторять в программе идентичные блоки кода, а описывать их однократно и вызывать по мере необходимости. К настоящему времени данная функция подпрограмм стала вспомогательной, главное их назначение — структуризация программы с целью удобства её понимания и сопровождения.Выделение набора действий в подпрограмму и вызов её по мере необходимости позволяет логически выделить целостную подзадачу, имеющую типовое решение. Такое действие имеет ещё одно (помимо экономии памяти) преимущество перед повторением однотипных действий: любое изменение (исправление ошибки, оптимизация, расширение функциональности), сделанное в подпрограмме, автоматически отражается на всех её вызовах, в то время как при дублировании каждое изменение необходимо вносить в каждое вхождение изменяемого кода.Даже в тех случаях, когда в подпрограмму выделяется однократно производимый набор действий, это оправдано, так как позволяет сократить размеры целостных блоков кода, составляющих программу, то есть сделать программу более понятной и обозримой...Подпрограммы часто используются для многократного выполнения стереотипных действий над различными данными. Подпрограмма обычно имеет доступ к объектам данных, описанным в основной программе (по крайней мере, к некоторым из них), поэтому для того, чтобы передать в подпрограмму обрабатываемые данные, их достаточно присвоить, например, глобальным переменным. Но такой путь не особенно удобен и чреват ошибками.Для обеспечения контролируемой передачи параметров в подпрограмму и возврата результатов из неё используется механизм параметров. Параметры описываются при описании подпрограммы (в её заголовке) и могут использоваться внутри процедуры аналогично переменным, описанным в ней. При вызове процедуры значения каждого из параметров указываются в команде вызова (обычно после имени вызываемой подпрограммы).В языках программирования высокого уровня используется два типа подпрограмм: процедуры и функции.• Функция — это подпрограмма специального вида, которая, кроме получения параметров, выполнения действий и передачи результатов работы через параметры имеет ещё одну возможность — она может возвращать результат. Вызов функции является, с точки зрения языка программирования, выражением, он может использоваться в других выражениях или в качестве правой части присваивания. Подробнее см. в статье Функция (программирование).• Процедура — это независимая именованная часть программы, которую после однократного описания можно многократно вызвать по имени из последующих частей программы для выполнения определенных действия.Подпрограммы, входящие в состав классов в объектных языках программирования, обычно называются методами. Этим термином называют любые подпрограммы-члены класса, как функции, так и процедуры; когда требуется уточнение, говорят о методах-процедурах или методах-функциях. 43. Этапы трансляции. Часто путают транслятор с языка программирования и систему программирования. Хотя «система программирования»- понятие гораздо большее, чем транслятор.Транслятор - это программа, которая переводит (с англ. translate) с нотации одного языка в нотацию другого языка.Трансляторы могут быть интерпретаторами (interpreter), т.е. совмещать анализ исходной программы с ее выполнением. Различие тут в том, что результатом работы интерпретатора будет не машинный код, а последовательность обращений к библиотеке функций интерпретатора.Интерпретатор в отличие от компилятора может выбирать одну за другой инструкции и сразу их выполнять. При интерпретации (это важно!!!), в отличии от трансляции или компиляции, может быть начато выполнение программы, которая содержит синтаксические ошибки. Кросс-трансляторы (кросс-компиляторы) - это вид трансляторов, которые переводят программу, записанную в нотации одного языка программирования и выполняющуюся в одной инструментальной среде, на одной ЭВМ, которая характеризуется своим операционным окружением и/или архитектурой, в код вычислительной системы другой среды другой ЭВМ. Редактор внешних связей моделирует размещение объектных модулей в ОП и разрешает все связи между ними.Иногда трансляторы в качестве результата трансляции выдают модуль на ассемблере соответствующей машины. В вышерассмотренную схему можно добавит этап оптимизации программы, причем оптимизация может происходить до этапа трансляции (т.е. в терминах исходного языка) и/или после трансляции (в терминах машинного кода). Например, до трансляции вычислить все const-ые выражения. Этот этап особенно важен для класса машин, относящихся к mainframe-ам.Этап трансляции. Каждый транслятор при обработке программы выполняет следующие действия:• лексический анализ;• синтаксический анализ;• семантический анализ и генерация кода.Иногда говорят о таких этапах:• лексический анализ;• синтаксический анализ;• внутренне представление кода• генерация кода.

1. На вход компилятора, а следовательно, и лексического анализатора поступает цепочка символов некоторого алфавита. Работа лексического анализатора заключается в том, чтобы сгруппировать определенные символы в единые синтаксические объекты, называемые лексемами. Какие объекты считать лексемами, зависит от определения языка. Кроме терминальных символов (+, –, /, *, (,)), которые сами по себе являются лексемами, в программе некоторые комбинации символов часто рассматриваются как единые объекты. Среди типичных примеров можно указать следующие.

• В некоторых языках цепочка, состоящая из одного или более пробелов, обычно рассматривается как один пробел.

• В языках программирования есть ключевые слова, такие, как begin, еnd, to, do, integer и другие, каждое из которых считается одним символом.

• Каждая цепочка, представляющая цифровую константу, рассматривается как один элемент текста.

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

2. Синтаксический анализ – второй этап компиляции. Во время этого этапа предложения программы распознаются как языковые конструкции используемой грамматики. Для того чтобы выяснить, принадлежит ли предложение языку, необходимо построить алгоритм, который для любого предложения, допустимого грамматикой, давал бы последовательность выводов этой цепочки к начальному символу грамматики. Мы можем рассматривать этот процесс как построение дерева грамматического разбора для транслируемых предложений. Различают две категории алгоритмов разбора: нисходящий (сверху вниз) и восходящий (снизу вверх). Эти термины соответствуют способу построения синтаксических деревьев. Рассмотрим для примера предложение 35 в грамматике целых чисел:

 

 

При нисходящем разборе дерево строится от корня (начального символа) вниз к концевым узлам (рис. 2).

 

 

Восходящий разбор состоит в том, что, отправляясь от заданной цепочки, пытаются привести ее к начальному символу (рис. 3).

 

3. ВНУТРЕННЕЕ ПРЕДСТАВЛЕНИЕ ПРОГРАММЫ

На выходе синтаксического анализатора формируется программа во внутреннем представлении.

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

1.3.1. Последовательность четверок

Каждая четверка записывается в виде

операция ор1, ор2, результат,

 

где операция – выполняемая объектным кодом функция; ор1, ор2 – операнды этой операции; результат определяет, куда должно быть помещено результирующее значение.

Например, предложение исходной программы (рис. 1): sum: = sum + а может быть представлено четверками следующим образом:

Здесь I1 обозначает промежуточный результат (sum + а), вторая четверка присваивает это значение переменной sum.

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

За операциями геаd и write следует четверка рaram, определяющая параметры операций read и write.

Четверка рaram будет, разумеется, при окончательной генерации машинного кода оттранслирована в список параметров. Операция > в четверке 3 сравнивает значение двух своих операндов и осуществляет переход к четверке 9, если первый операнд больше второго. Операция goto в четверке 8 осуществляет безусловный переход к четверке 3.


Дата добавления: 2015-07-15; просмотров: 187 | Нарушение авторских прав


Читайте в этой же книге: История ОПП | Основные идеи ОПП | Вопрос 9. Понятие об ООП. Основные принципы и идеи ООП. | Понятие полиморфизма. Использование в языке. | Абстрактые классы, виртуальные методы. Наследование и замещение методов. | Параметризация типов данных в классах и функциях. | Разделение массива | Сбалансированные деревья | Многоключевые деревья | Матрица смежности |
<== предыдущая страница | следующая страница ==>
Основы алгоритмов криптографии.| Генерация кода

mybiblioteka.su - 2015-2024 год. (0.013 сек.)