Базовые конструкции структурного программирования.




Константы.

Константами называют неизменяемые величины. Различают целые, вещественные, символьные и строковые константы.

Константа Формат Примеры
Целая Десятичный: последовательность десятичных цифр, начинающаяся не с нуля, если это не число ноль Восьмеричный: ноль, за которым следуют восьмеричные цифры Шестнадцатеричный: 0х или 0Х, за которым следуют шестнадцатеричные цифры 8, 0, 199226   01, 020, 07155   0хA, 0x1B8, 0XFF
Вещественная Десятичный: [цифры].[цифры] Экспоненциальный: [цифры][.][цифры]{Е|е}[+|-][цифры] 5.7,.001, 35.   0.2Е6,.11е-3, 5Е10
Символьная Один или два символа, заключенных в апострофы ‘А’, ‘ю’, ‘*’, ‘db’, ‘\0’, ‘\n’, ‘\х07\х07’
Строковая Последовательность символов, заключенная в кавычки “Мама мыла раму”, “3,14”

Если требуется сформировать отрицательную целую или вещественную константу, то перед константой ставится знак «-».

Символ обратной косой черты используется для представления:

- кодов, не имеющих графического изображения: \a – звуковой сигнал, \b – возврат на шаг, \f – перевод страницы, \n – перевод строки, \r – возврат каретки, \t - горизонтальная табуляция, \v – вертикальная табуляция;

- символов апострофа (\’), кавычек (\”), вопросительного знака (\?), обратной косой черты (\\);

- любого символа с помощью его шестнадцатеричного или восьмеричного кода.

Последовательности символов, начинающиеся с обратной косой черты, называют управляющими, или escape-последовательностями. Управляющие последовательности могут использоваться и в строковых константах, называемых строковыми литералами. Например, “Издательский дом \ “Питер \””.

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

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

 

Переменные и выражения.

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

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

[класс памяти] [const] тип имя [инициализатор];

Необязательный класс памяти может принимать одно из значений auto, extern, static и register.

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

При описании можно присвоить переменной начальное значение, это называется инициализацией. Инициализатор можно записывать в двух формах – со знаком равенства: = значение или в круглых скобках: (значение). Константа должна быть инициализирована при объявлении.

В одном операторе можно описать несколько переменных одного типа, разделяя их запятыми.

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

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

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

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

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

Время жизни может быть постоянным (в течение выполнения программы) и временным (в течение выполнения блока).

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

Для задания класса памяти используются следующие спецификаторы:

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

- extern – означает, что переменная определяется в другом месте программы (в другом файле или дальше по тексту). Используется для создания переменных, доступных во всех модулях программы, в которой они объявлены. Если переменная в том же операторе инициализируется, то данный спецификатор игнорируется;

- static – статическая переменная. Время жизни – постоянное. Инициализируется один раз при первом выполнении оператора, содержащего определение переменной. В зависимости от расположения оператора описания статические переменные могут быть глобальными и локальными. Глобальные статические переменные видны только в том модуле, в котором они описаны;

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

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

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

 

Знаки операций в Си++

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

Унарные операции

& получение адреса операнда
* Обращение по адресу (разыменование)
- унарный минус, меняет знак арифметического операнда
~ поразрядное инвертирование внутреннего двоичного кода целочисленного операнда (побитовое отрицание)
! логическое отрицание (НЕ). В качестве логических значений используется 0 - ложь и не 0 - истина, отрицанием 0 будет 1, отрицанием любого ненулевого числа будет 0.
++ Увеличение на единицу: префиксная операция - увеличивает операнд до его использования, постфиксная операция увеличивает операнд после его использования. int m=1,n=2; int a=(m++)+n; // a=4,m=2,n=2 int b=m+(++n);//a=3,m=1,n=3
- - уменьшение на единицу: префиксная операция - уменьшает операнд до его использования, постфиксная операция уменьшает операнд после его использования.
sizeof вычисление размера (в байтах) для объекта того типа, который имеет операнд имеет две формы sizeof выражение sizeof (тип) Примеры: sizeof(float)//4 sizeof(1.0)//8, т. к. вещественные константы по умолчанию имеют тип double

Бинарные операции.

Аддитивные:

+ бинарный плюс (сложение арифметических операндов)
- бинарный минус (вычитание арифметических операндов)

Мультипликативные:

* умножение операндов арифметического типа
/ деление операндов арифметического типа (если операнды целочисленные, то выполняется целочисленное деление)
% получение остатка от деления целочисленных операндов

Операции сдвига (определены только для целочисленных операндов).

Формат выражения с операцией сдвига:

операнд_левый операция_сдвига операнд_правый

<< сдвиг влево битового представления значения левого целочисленного операнда на количество разрядов, равное значению правого операнда, освободившиеся разряды обнуляются
>> сдвиг вправо битового представления значения правого целочисленного операнда на количество разрядов, равное значению правого операнда, освободившиеся разряды обнуляются, если операнд беззнакового типа и заполняются знаковым разрядом, если – знакового

Поразрядные операции:

& поразрядная конъюнкция (И) битовых представлений значений целочисленных операндов (бит =1, если соответствующие биты обоих операндов=1)
| поразрядная дизъюнкция (ИЛИ) битовых представлений значений целочисленных операндов (бит =1, если соответствующий бит одного из операндов=1)
^ поразрядное исключающее ИЛИ битовых представлений значений целочисленных операндов(бит =1, если соответствующий бит только одного из операндов=1)

Операции сравнения: результатом являются true(не 0) или false(0)

< меньше, чем
> больше, чем
<= меньше или равно
>= больше или равно
== Равно
!= не равно

Логические бинарные операции:

&& конъюнкция (И) целочисленных операндов или отношений, целочисленный результат ложь(0) или истина(не 0)
|| дизъюнкция (ИЛИ) целочисленных операндов или отношений, целочисленный результат ложь(0) или истина(не 0)

Операции присваивания

=, +=, -=, += и т.д.

Формат операции простого присваивания:

операнд1=операнд2

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

Условная операция.

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

Выражение1? Выражение2: Выражение3;

Первым вычисляется значение выражения1. Если оно истинно, то вычисляется значение выражения2, которое становится результатом. Если при вычислении выражения1 получится 0, то в качестве результата берется значение выражения3.

Например:

x<0? -x: x; //вычисляется абсолютное значение x.

Операция явного (преобразования) приведения типа.

Существует две формы: каноническая и функциональная:

1) (имя_типа) операнд

2) имя_типа (операнд)

(int)a //каноническая форма

int(a) //функциональная форма

Выражения

Из констант, переменных, разделителей и знаков операций можно конструировать выражения. Каждое выражение представляет собой правило вычисления нового значения.. Если выражение формирует целое или вещественное число, то оно называется арифметическим. Пара арифметических выражений, объединенная операцией сравнения, называется отношением. Если отношение имеет ненулевое значение, то оно – истинно, иначе – ложно.

Приоритеты операций в выражениях

Ранг Операции
  () [ ] ->.
  ! ~ - ++ -- & * (тип) sizeof тип()
  * / % (мультипликативные бинарные)
  + - (аддитивные бинарные)
  << >> (поразрядного сдвига)
  < > <= >= (отношения)
  ==!= (отношения)
  & (поразрядная конъюнкция «И»)
  ^ (поразрядное исключающее «ИЛИ»)
  | (поразрядная дизъюнкция «ИЛИ»)
  && (конъюнкция «И»)
  || (дизъюнкция «ИЛИ»)
  ?: (условная операция)
  = *= /= %= -= &= ^= |= <<= >>= (операция присваивания)
  , (операция запятая)

 

Ввод и вывод данных

В языке Си++ нет встроенных средств ввода и вывода – он осуществляется с помощью функций, типов и объектов, которые находятся в стандартных библиотеках. Существует два основных способа: функции унаследованные из Си и объекты Си++.

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

1) printf (форматная строка, список аргументов);

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

printf (“Значение числа Пи равно %f\n”, pi);

Форматная строка может содержать

1) символы печатаемые текстуально;

2) спецификации преобразования;

3) управляющие символы.

Каждому аргументу соответствует своя спецификация преобразования:

%d, %i - десятичное целое число;

%f - число с плавающей точкой;

%e,%E – число с плавающей точкой в экспоненциальной форме;

%u – десятичное число в беззнаковой форме;

%c - символ;

%s - строка.

В форматную строку также могут входить управляющие символы:

\n - управляющий символ новая строка;

\t – табуляция;

\a – звуковой сигнал и др.

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

%[-]m[.p]C, где

1. - задает выравнивание по левому краю,

m – минимальная ширина поля,

p – количество цифр после запятой для чисел с плавающей точкой и минимальное количество выводимых цифр для целых чисел (если цифр в числе меньше, чем значение р, то выводятся начальные нули),

С- спецификация формата вывода.

Пример

printf("\nСпецификации формата:\n%10.5d - целое,\n%10.5f - с плавающей точкой\

\n%10.5e – в экспоненциальной форме\n%10s - строка",10,10.0,10.0,"10");

Будет выведено:

Спецификации формата:

00010 – целое

10.00000 – с плавающей точкой

1.00000е+001 - в экспоненциальной форме

10 – строка.

2) scanf (форматная строка, список аргументов);

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

scanf(“ %d%f ”, &x,&y);

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

1) << - операция записи данных в поток;

2) >> - операция чтения данных из потока.

Например:

#include <iostream.h>;

.........

cout << “\nВведите количество элементов: ”;

cin >> n;

 

Рассмотрим основные операции.

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

Пример.

#include <stdio.h>

int main() {

int x=3, y=3;

printf(“Значение префиксного выражения: %d\n”, ++x);

printf(“Значение постфиксного выражения: %d\n”, y++);

printf(“Значение х после приращения: %d\n”, x);

printf(“Значение y после приращения: %d\n”, y);

return 0;

}

Результат работы программы:

Значение префиксного выражения: 4

Значение постфиксного выражения: 3

Значение х после приращения: 4

Значение y после приращения: 4

Операндом операции инкремента в общем случае является так называемое L-значение. Так обозначается любое выражение, адресующее некоторый участок памяти, в который можно занести значение. Переменная является частным случаем L-значения.

Операция определения размера sizeof предназначена для вычисления размера объекта или типа в байтах, и имеет две формы: sizeof выражение или sizeof (тип).

Операции отрицания (-,! и ~). Арифметическое отрицание (унарный минус -) изменяет знак операнда целого или вещественного типа на противоположный. Логическое отрицание (!) дает в результате значение 0, если операнд есть истина (не нуль), и значение 1, если операнд равен нулю. Операнд должен быть целого или вещественного типа, а может иметь тип указатель. Поразрядное отрицание (~), часто называемое побитовым, инвертирует каждый разряд в двоичном представлении целочисленного операнда.

Деление (/) и остаток от деления (%). Операция деления применима к операндам арифметического типа. Если оба операнда целочисленные, результат операции округляется вниз до целого числа, в противном случае тип результата определяется правилами преобразования. Операция остатка от деления применяется только к целочисленным операндам.

Операции сдвига (<< и >>) применяются к целочисленным операндам. Они сдвигают двоичное представление первого операнда влево или вправо на количество двоичных разрядов, заданное вторым операндом. При сдвиге влево (<<) освободившиеся разряды обнуляются. При сдвиге вправо (>>) освободившиеся биты заполняются нулями, если первый операнд беззнакового типа, и знаковым разрядом в противном случае. операции сдвига не учитывают переполнение и потерю значимости.

Операции отношения (<, <=, >, >=, ==,!=) сравнивают первый операнд со вторым. Операнды могут быть арифметического типа или указателями. Результатом операции является значение true или false. Операции сравнения на равенство и неравенство имеют меньший приоритет, чем остальные операции сравнения.

Поразрядные операции (&, |, ^) применяются только к целочисленным операндам и работают с их двоичными представлениями. При выполнении операций операнды сопоставляются побитово. При поразрядной конъюнкции, или поразрядном И (&) бит результата равен 1 только тогда, когда соответствующие биты обоих операндов равны 1. При поразрядной дизъюнкции, или поразрядном ИЛИ (|) бит результата равен 1 тогда, когда соответствующий бит хотя бы одного из операндов равен 1. При поразрядном исключающем ИЛИ (^) бит результата равен 1 только тогда, когда соответствующий бит только одного из операндов равен 1.

Логические операции (&& и ||). Операнды логических операций И (&&) и ИЛИ (||) могут иметь арифметический тип или быть указателями, при этом операнды в каждой операции могут быть различных типов.

Операции присваивания (=, +=, -=, *= и т.д.). В операции простого присваивания (=) слева от знака должно находиться L-значение, а справа – выражение. При присваивании производится преобразование типа выражения к типу L-значения, что может привести к потере информации. В сложных операциях присваивания при вычмслении выражения, стоящего в правой части, используется и L-значение из левой части. Например, выражение a+=b является более компактной записью выражения a=a+b.

Условная операция (?:). Эта операция тернарная, то есть имеет три операнда. Ее формат: операнд1? операнд2: операнд3. Первый операнд может иметь арифметический тип или быть указателем. Он оценивается с точки зрения его эквивалентности нулю. Если результат вычисления операнда1 равен истина, то результатом условной операции будет значение второго операнда, иначе – третьего операнда. Условная операция является сокращенной формой условного оператора if.

Стандартно выполняются операции умножения (*), сложение (+) и вычитание (-).

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

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

Преобразования бывают двух типов:

- изменяющие внутреннее представление величин (с потерей точности или без потери точности);

- изменяющие только интерпретацию внутреннего представления.

К первому типу относится, например, преобразование целого числа в вещественное (без потери точности) и наоборот, ко второму – преобразование знакового целого в беззнаковое.

 

Базовые конструкции структурного программирования.

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

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

Рассмотрим операторы языка, реализующие базовые конструкции структурного программирования.

Оператор «выражение»

Любое выражение, завершающееся точкой с запятой, рассматривается как оператор, выполнение которого заключается в вычислении выражения. Частным случаем является пустой оператор; (он используется, когда по синтаксису оператор требуется, а по смыслу – нет).

Операторы ветвления

Условный оператор if используется для разветвления процесса вычислений на два направления. Формат оператора:

if (выражение) оператор1; [else оператор2;]

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

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

Оператор switch (переключатель) предназначен для разветвления процесса вычислений на несколько направлений. Формат оператора:

switch (выражение) {

case константное выражение1: [операторы1]

case константное выражение2: [операторы2]

case константное выражениеn: [операторыn]

[default: операторы]

}

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

Выход из переключателя обычно выполняется с помощью операторов break или return.

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

Операторы цикла

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

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

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

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

Для удобства в С++ есть три разных оператора цикла – while, do while, for.

Цикл с предусловием while имеет вид:

while (выражение) оператор;

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

Распространенный прием программирования – организация бесконечного цикла с заголовком while (true) или while(1) и принудительным выходом из тела цикла по выполнению какого-либо условия.

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

Цикл с постусловием do while имеет вид:

do оператор while выражение;

сначала выполняется оператор тела цикла, а затем вычисляется выражение. Если оно истинно, тело цикла выполняется еще раз. Цикл завершается, когда выражение станет равным false или в теле цикла будет выполнен какой-либо оператор передачи управления. Тип выражения должен быть арифметическим или приводимым к нему.

Цикл с параметром for имеет следующий формат:

for (инициализация; выражение; модификации) оператор;

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

Выражение определяет условие выполнения цикла: если его результат, приведенный к типу bool, равен true, цикл выполняется.

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

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

Чтобы избежать ошибок, рекомендуется:

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

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

- предусмотреть аварийный выход из цикла по достижению некоторого количества итераций;

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



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2022-05-15 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: