Определение количества информации. Единицы измерения информации. 4 страница

Языки программирования также можно классифицировать на процедурные и непроцедурные.

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

Среди процедурных языков выделяют в свою очередь структурные и операционные языки. В структурных языках одним оператором записываются целые алгоритмические структуры: ветвления, циклы и т.д. В операционных языках для этого используются несколько операций. Широко распространены следующие структурные языки: Паскаль, Си, Ада, ПЛ/1. Среди операционных известны Фортран, Бейсик, Фокал.

Непроцедурное (декларативное) программирование появилось в начале 70-х годов 20 века, К непроцедурному программированию относятся функциональные и логические языки.

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

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

Можно выделить еще один класс языков программирования – объектно–ориентированные языки высокого уровня. На таких языках не описывают подробной последовательности действий для решения задачи, хотя они содержат элементы процедурного программирования. Объектно–ориентированные языки, благодаря богатому пользовательскому интерфейсу, предлагают человеку решить задачу в удобной для него форме.

Первый объектно-ориентированный язык программирования Simula был создан в 1960-х годах Нигаардом и Далом.

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

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

25 Основные понятия объектно-ориентированного программирования: объект, событие, инкапсуляция, наследование, полиморфизм, класс объектов.

Объе́ктно-ориенти́рованное программи́рование (ООП) — парадигма программирования, в которой основными концепциями являются понятия объектов и классов. В случае языков с прототипированием вместо классов используются объекты-прототипы.

Класс

Класс является описываемой на языке терминологии исходного кода моделью ещё не существующей сущности (объекта). Фактически он описывает устройство объекта, являясь своего рода чертежом. Говорят, что объект — это экземпляр класса. При этом в некоторых исполняющих системах класс также может представляться некоторым объектом при выполнении программы посредством динамической идентификации типа данных. Обычно классы разрабатывают таким образом, чтобы их объекты соответствовали объектам предметной области.

Объект

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

Инкапсуляция — это свойство системы, позволяющее объединить данные и методы, работающие с ними, в классе, и скрыть детали реализации от пользователя

Наследование — это свойство системы, позволяющее описать новый класс на основе уже существующего с частично или полностью заимствующейся функциональностью. Класс, от которого производится наследование, называется базовым, родительским или суперклассом. Новый класс — потомком, наследником, дочерним или производным классом.

Полиморфизм — это свойство системы использовать объекты с одинаковым интерфейсом без информации о типе и внутренней структуре объекта. При использовании термина «полиморфизм» в сообществе ООП подразумевается полиморфизм подтипов; а использование параметрического полиморфизма называют обобщённым программированием.

26 Свойства и методы и события объектов в объектно-ориентированном программировании.

Событие в объектно-ориентированном программировании — это сообщение, которое возникает в различных точках исполняемого кода при выполнении определённых условий.

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

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

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

Метод в объектно-ориентированном программировании — это функция или процедура, принадлежащая какому-то классу или объекту.

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

Различают простые методы и статические методы (методы класса):

простые методы имеют доступ к данным объекта (конкретного экземпляра данного класса),

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

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

В зависимости от того, какой уровень доступа предоставляет тот или иной метод, выделяют:

открытый (public) интерфейс — общий интерфейс для всех пользователей данного класса;

защищённый (protected) интерфейс — внутренний интерфейс для всех наследников данного класса;

закрытый (private) интерфейс — интерфейс, доступный только изнутри данного класса.

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

27 Визуальное объектно-ориентированное событийное программирование, понятия: проект, форма, управляющие элементы.

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

Форма – основной элемент внешнего интерфейса проекта, аналог окна Windows. Она имеет строку заголовка с кнопками управления и системным меню, а также возможности управления мышью. Все это не надо программировать, форма, включённая в проект, обладает этими свойствами. Форма хранится в файле с расширением frm, она предназначена для размещения элементов настройки и управления проекта, для обмена информацией с пользователем при работе приложения. Это сложный программный объект, имеющий характерные свойства, методы, события. Кроме того, в файле формы хранится описание помещенных на нее элементов управления, программный код процедур, относящихся к данной форме. Обычно в проекте бывает несколько форм.

Проект – приложение на стадии разработки

Стандартный набор управляющих элементов размещается на вкладке Standart и включает в себя 16 классов объектов: командная кнопка (Button), текстовое поле (Edit), надпись Label) и т.д.

28 Общие сведения о среде визуального объектно-ориентированное событийное программирования Visual Basic.

языках визуального объектно-ориентированного программирования (например, Visual Basic) применяется визуальный метод создания графического интерфейса приложения и объектный метод построения его программного кода.

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

В роли основных объектов при визуальном программировании выступают формы (Forms). Форма представляет собой окно, на котором размещаются управляющие элементы. Управляющие элементы — это командные кнопки (CommandButton), переключатели, или «флажки» (Checkbox), поля выбора, или «радиокнопки» (OptionsButton), списки (ListBox), текстовые поля (TextBox) и др.

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

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

29 Переменные, константы и типы данных в Visual Basic.

Типом данных называется способ хранения и представления данных в компьютерной системе.

В языке Visual Basic могут храниться и обрабатываться данные следующих типов.

Byte — целое неотрицательное число. Принимает значения от 0 до 255, занимает 1 байт.

Boolean — логическая величина. Принимает одно из двух значений True и False, занимает 2 байта.

Currency — десятичное протяженное число. Используется для проведения денежных вычислений с фиксированным количеством знаков после десятичной запятой, занимает 8 байт. (До 15 знаков слева от десятичной точки и до 4 знаков справа от десятичной точки).

Date — дата. Используется для хранения дат/времени, занимает 8 байт.

Double — десятичное число двойной точности, занимает 8 байт.

Integer — короткое целое числовое значение, занимает 2 байта. Используется для представления целых чисел в диапазоне от -32768 до 32767.

Long — длинное целое число, занимает 4 байта. Используется для представления целых чисел в диапазоне от -2147483648 до 2147483647.

Single — десятичное число обычной точности, занимает 4 байта. Используется для представления отрицательных чисел в диапазоне от -3.402823Е 38 до -1.401298Е-45 и для представления положительных чисел в диапазоне от 1.401298Е-45 до 3.402823Е 38.

String — строка переменной длины. Занимаемая память линейно зависит от числа символов в строке.

String * длина — строка постоянной длины.

Variant — произвольное значение. Используется для хранения данных любых типов. Занимает 16 байтов плюс по одному байту на каждый символ, если значением является строка.

Object — объект. Используется только для хранения ссылок на объекты, занимает 4 байта.

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

Имя переменной (идентификатор) — это строка символов, которая отличает эту переменную от других объектов программы (идентифицирует переменную в программе).

При задании имен переменным нужно соблюдать следующие правила:

первым символом имени должна быть буква. Остальные символы — буквы и цифры (прописные и строчные буквы различаются). Можно использовать символ «_»;

в имени нельзя использовать символ «.»;

число символов в имени не должно превышать 255;

имя переменной не должно совпадать с зарезервированными (служебными) словами языка.

В Visual Basic существуют следующие возможности. объявления типа переменной.

Переменная может вообще не объявляться. В этом случае будет установлен по умолчанию тип Variant. Однако это может привести к медленной неэффективной работе программы и нерациональному использованию памяти.

Переменная может объявляться явно с помощью оператора определения переменной:

Dim имяПеременной [ As типПеременной],
например: Dim d as Long.

Чтобы переменные всегда объявлялись явно, нужно использовать опцию Option Explicit в секции (General) (Declarations) существующих форм, модулей или классов. После установки этой опции Visual Basic требует явного описания переменных и при использовании в коде необъявленной переменной выдаст сообщение об ошибке.

Переменная может объявляться неявно:

• с помощью оператора объявления типа:

DеfТип Начальная буква [— Конечная буква];

• вместо ОегТип указывается одно из ключевых слов, обозначающих тип:

— Deflnt (для типа Integer);
— DefLng (для типа Long);
— DefSng (для типа Single);
— DefStr (для типа String) и так далее;

• о типе переменной можно иногда судить по суффиксу, приписываемому к имени переменной. Суффиксы могут быть только у шести типов переменных:

— % — тип Integer;
— & — тип Long;
—! — тип Single;
— # — тип Double;
— $ — тип String;
— @ — тип Currency.

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

Константы — величины, значения которых не могут меняться. Как и переменные, константы объявляются в начале текста программного кода оператором:

Const ИмяКонстанты [As Тип] = Значение, например: Const Pi = 3.14159

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

30 Классификация операционных систем: однозадачные - многозадачные, однопользовательские – многопользовательские, сетевые; с командным и оконным интерфейсом, с текстовым и графическим интерфейсом.

Однозадачные ОС - такие, в которых в один момент времени может выполнятся одна программа. В настоящее время большинство разрабатываемых операционных систем многозадачные, однако есть исключения (например, FreeDOS).

почти все современные операционные системы (Windows 95, Windows NT, Windows 2000, Unix) поддерживают преимущественную многозадачность {preemptive multi-tasking). Этот термин, который часто переводят как вытесняющая многозадачность, означает, что процесс или, точнее, его поток, который в данный момент активен, имеет преимущество перед другими конкурирующими потоками с одинаковым приоритетом. Системы Windows 3.1 и Macintosh поддерживают кооперативную многозадачность {cooperative multi-tasking), в которой все управление отдано системе. В такой системе легче программировать, но она менее эффективна.

Основным признаком многозадачной ОС является способность совмещать выполнение нескольких прикладных программ. Большое значение при этом имеет способ совмещения, то есть на каком уровне или как конкретно реализовано совмещение. Если однопроцессорная, но многозадачная, система выделяет каждой прикладной программе определенный квант времени {lime slice), спустя который она переключается на выполнение следующей программы, то это система с разделением времени {time-sharingsystem). Системы с разделением времени появились в начале 60-х. Они управлялись main /rame-компьютерами, обслуживающими многочисленные удаленные терминалы. В качестве терминалов сначала использовались обычные телетайпы, которые умели только вводить или выводить информацию. Благодаря огромной разнице в скорости работы таких устройств, как телетайп и процессор, системы с разделением времени успевали переключаться между многими терминалами и вводить или выводить информацию так, что каждому пользователю казалось, что он единолично управляет удаленным процессором. Затем появились персональные компьютеры, которые стали использоваться в качестве удаленных терминалов. В связи с этим для операционной системы главного процессора (например, IBM-370) отпала необходимость заниматься посимвольным вводом-выводом. Теперь акцент в разработке операционных систем был перенесен на управление выполняемыми программными модулями, принадлежащими разным пользователям и одновременно находящимися в памяти главного компьютера. Появились такие понятия, как очередь заданий •-- очередь на обслуживание каким-либо устройством: принтером, плоттером, накопителем на магнитном носителе, приоритет задания, ожидаемое время завершения задания и т. д.

Многопользовательская система, система с коллективным доступом, система коллективного доступа (multiuser system, multiaccess system) - вычислительная система или ее часть (например операционная система), позволяющая нескольким пользователям одновременно иметь доступ к одной ЭВМ со своего терминала (локального или удаленного). Многопользовательский характер работы достигается благодаря режиму разделения времени, который заключается в очень быстром переключении ЭВМ между разными терминалами и программами и соответственно быстрой отработке команд каждого пользователя. При этом последний не замечает задержек времени, связанных с обслуживанием других пользователей. Примерами разработок указанного вида могут служить помимо Windows операционные системы: NetWare, созданная и развиваемая фирмой Novell (США) для локальных информационных вычислительных систем; Unix фирмы AT&T’s Bell Laboratories (США); REAL/32 и др.

* Однопользовательская система (one user system) - операционная система, не обладающая свойствами многопользовательской. Примерами однопользовательских ОС являются MS DOS фирмы Microsoft (США) и ОС/2, созданная совместно Microsoft и IBM.

* Сетевая операционная система, СОС (NOS, Network Operating System) - операционная система, предназначенная для обеспечения работы вычислительной сети. Примерами сетевых операционных систем являются Windows NT, Windows 2000, Novel Netware, Unix, Linux и др

Наиболее распространённое использование интерфейса командной строки — командный интерпретатор, используемый как интерфейс управления операционной системой. Это широко распространённая практика в ОС POSIX-совместимого семейства: Linux, xBSD QNX и других. Также это основной интерфейс многих старых ОС, включая CP/M и основанных на ней — MS-DOS и пр.

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

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

Интерфейс командной строки используется в разнообразных устройствах. Hayes-модем используют стандартизированный набор AT-команд посылаемых с компьютера. Многие встроенные системы также используют командный интерфейс в качестве технологического.

Линейные операционные системы реализуют интерфейс командной строки. Основным устройством управления в них является клавиатура. Команда набирается на клавиатуре и отображается на экране дисплея. Окончанием ввода команды служит нажатие клавиши Enter. Для работы с операционными системами, имеющими текстовый интерфейс, необходимо овладеть командным языком данной среды, т.е. совокупностью команд, структура которых определяется синтаксисом этого языка.

Первые настоящие операционные системы имели текстовый интерфейс. В настоящее время он также используется на серверах и компьютерах пользователей.

31 Основные принципы организации и функционирования операционных систем, их состав и структура. Управление данными. Файловые системы. Управление заданиями.

Принцип модульности

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

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

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

Принцип функциональной избирательности

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

Принцип генерируемости ОС

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

Упомянутый раньше принцип модульности положительно проявляется при генерации ОС. Он существенно упрощает настройку ОС на требуемую конфигурацию вычислительной системы. В наши дни при использовании персональных компьютеров с принципом генерируемости ОС можно столкнуться разве что только при работе с Linux. В этой UNIX-система имеется возможность не только использовать какое-либо готовое ядро ОС, но и самому сгенерировать (скомпилировать) такое ядро, которое будет оптимальным для данного конкретного персонального компьютера и решаемых на нем задач. Кроме генерации ядра в Linux имеется возможность указать и набор подгружаемых драйверов и служб, то есть часть функций может реализовываться модулями, непосредственно входящими в ядро системы, а часть - модулями, имеющими статус подгружаемых, транзитных.

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

Принцип функциональной избыточности

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

Принцип виртуализации

Принцип виртуализации: построение виртуальных ресурсов, их распределение и использование в настоящее время применяется практически в любой ОС. Этот принцип позволяет представить структуру системы в виде определенного набора планировщиков процессов и распределителей ресурсов (мониторов) и использовать единую централизованную схему распреде-ления ресурсов.

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

- единообразная по логике работы виртуальная память практически неограниченного объема.

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

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

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

Принцип совместимости

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

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

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

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

Управление данными — важнейший компонент операционной системы, так как осуществляет связь вычислительной системы с «окружающей средой»: реализует запросы на ввод-вывод, исходящие как от программы пользователя, так и от программы операционной системы.

Основные функции управления данными.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: