Вы находитесь на странице: 1из 18

Отчет

по лабораторной работе № 1
по дисциплине алгоритмизация и компьютерное программирование
Тема: Разработка программ с использованием базовых конструкций языка С+
+
Цель: научиться использовать средства ввода/вывода данных
управляющие конструкции (условные, циклические) языка С++;
научиться разрабатывать и вызывать пользовательские функции, в том
числе с использованием массивов и указателей.
Модуль 1 Изучение структуры программы и конструкций языка С++
Задание

1. Условие задачи:

Написать программы для решения следующих задач


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

2. UML-диаграмма классов.

3. Программный код.

#include<iostream>
#include<string>
using namespace std;
struct rectangle
{
float L;
float W;
string color;
};

int main(void)
{
setlocale(LC_ALL, "Russian"); // установить кирилический шрифт в консоли
rectangle a, b;
a.L = 3.2;
a.W = 1.4;
a.color = "green";

cout << "Введите длину";


cin >> b.L;
cout << "Введите ширину";
cin >> b.W;
float S1;
float S2;
S1 = a.L * a.W;
S2 = b.L * b.W;
cout << "Больший прямоугольник ";
if (S1 > S2) cout << "S1";
else cout << "S2";
float L1;
float st;
float L2;
float S;
float stv;
cout << "Введите стоимость";
cin >> st;

L1 = a.L + a.W;
L2 = b.L + b.W;
S = L1 + L2;
stv = st * S;
cout << stv;

1. Тестирование работы программы.

Структура Пример
тест-кейса
№ тест-кейса. 1 Анализ простой дроби
Краткое Шаги:
описание 1 Запустить программу
Предусловие Ввести значение длины 5
(может Ввести значение ширины 7
отсутствова Ввести значение стоимости лент 5
ть) Ожидаемый результат
Описать, что На экран должно быть выведено:
должно быть Площадь большего прямоугольника. 35
выполнено до Стоимость обклейки лентой первого и второго
начала Прямоугольников. 120 и 110
выполнения
тест-кейса,
Фактический результат:
например,
заполнить
список
данными т. д.
Шаги
Перечислить
последовательн
ость действий,
какие
конкретно
данные ввести
в ответ на
запрос
программы.
Ожидаемый
результат
выполнения
программы
Фактический
результат
выполнения
программы
Привести
экранную
форму из
работающей
программы.
Если совпадает
с ожидаемым
результатом –
тест пройден.

Условие задачи:

Написать программы для решения следующих задач


1 Создать массив студентов, в котором хранятся фамилия и результат
сдачи теста и заполнить его данными.
Вывести в форме ведомости данные о сдаче экзамена. Цифровое
значение отметки продублировать текстом.
Определить сколько студентов не набрали проходной балл.
Вывести списки студентов прошедших и непрошедших тест.
1. UML-диаграмма классов.
2. Программный код.
#include <iostream>
using namespace std;
int main() {
setlocale(LC_ALL, "Russian");
struct Student {
string surname;
int mark;
};
Student Students[] = { {"Колос", 8}, {"Василькова", 9}, {"Харук", 3},
{"Яковлев",5}, };
int n = sizeof(Students) / sizeof(Students[0]);
for (int i = 0, number = 1; i < n; i++) {
if (Students[i].mark > 3) {
cout << number++ << ". " << Students[i].surname << " " <<
Students[i].mark << '(';

switch (Students[i].mark) {
case 0: cout << "Ноль";
break;
case 1: cout << "Один";
break;
case 2: cout << "Два";
break;
case 3: cout << "Три ";
break;
case 4: cout << "Четыре";
break;
case 5: cout << "Пять";
break;
case 6: cout << "Шесть";
break;
case 7: cout << "Семь";
break;
case 8: cout << "Восемь";
break;
case 9: cout << "Девять";
break;
case 10: cout << "Десять";
break;
default:
cout << " Нет такой отметки! ";
}; cout << ")" << endl;
}
}
return 0;
}

Структура Пример
тест-кейса
№ тест- 1 Анализ сдачи теста студентами
кейса. Шаги:
Краткое Запустить программу
описание Ввести студентов и их оценки
Предуслови Ожидаемый результат
е (может На экран должно быть выведено:
отстуствов Фамилия, оценка, оценка словами
ать)
Описать, что
должно быть
выполнено до
начала
выполнения
тест-кейса,
например
заполнить
список
данными т. д.
Шаги
Перечислить
последовател
ьность
действий,
какие
конкретно
данные
ввести в
ответ на
запрос
программы.
Ожидаемый
результат
выполнения
программы
Фактически
й результат
выполнения
программы
Привести
экранную
форму из
работающей
программы.
Если
совпадает с
ожидаемым
результатом
– тест
пройден.

1. Условие задачи:

Даны координаты концов двух отрезков. Определить, какой из отрезков


длиннее? Вычисление длины отрезка реализовать в виде функции
пользователя.
2. UML-диаграмма классов.
3. Программный код.
#include<iostream>

#include<cmath>

using namespace std;

struct Point {
float x;
float y;
};

float getDistance(Point, Point);

void input(Point*);
int main()
{
setlocale(LC_ALL, "Russian");
Point A1, B1;
cout << "введите координаты А1" << endl;
input(&A1);
cout << "введите координаты B1" << endl;
input(&B1);
cout << "длинна первого:" << getDistance(A1, B1) << endl;

Point A2, B2;

cout << "введите координаты А2" << endl;


input(&A2);

cout << "введите координаты B2" << endl;

input(&B2);

cout << "длинна второго:" << getDistance(A2, B2);

float getDistance(Point A, Point B)

{
return sqrt((B.x - A.x) * (B.x - A.x) + (B.y - A.y) * (B.y - A.y));

void input(Point * thePoint) {

cout << "x";

cin >> thePoint->x;

cout << "y";

cin >> thePoint->y;

}
4. Тестирование работы программы.
Структура тест-кейса Пример
№ тест-кейса. Краткое описание 1 Анализ простой дроби Шаги
Предусловие (может отсутство- 1 Запустить программу
вать) 1.Ввести координаты А1 5 6
Описать, что должно быть выполнено до 2.Ввести координаты Б1 7 8
начала выполнения тест-кейса, например, 3.Ввести координаты А2 8 9
заполнить список данными т. д.
4.Ввести координаты Б2 5 9
Шаги
Перечислить последовательность
действий, какие конкретно данные ввести Ожидаемый результат
в ответ на запрос программы. На экран должно быть выведено:
Ожидаемый результат выполнения Длинна первого 2.82
программы Длинна второго 3
Фактичсекий результат выполнения
программы Фактический результат:
Привести экранную форму из
работающей программы. Если совпадает
с ожидаемым результатом – тест
пройден.
Даны два трехзначных целых числа. С помощью функции пользователя
число, у которого первая цифра в записи большее заменить 1, а у которого
меньше - -1.
#include <iostream>
using namespace std;

void Foo1(int *n, int &n2)


{
int a, b, c;

a = *n / 100;
b = *n % 100 / 10;
c = *n % 10;

int a2, b2, c2, x2;

a2 = n2 / 100;
b2 = n2 % 100 / 10;
c2 = n2 % 10;

if (a < a2)
{
a = 1;

*n = (a * 10 + b) * 10 + c;

a2--;

n2 = (a2 * 10 + b2) * 10 + c2;


}
else
{
a--;

*n = (a * 10 + b) * 10 + c;
a2 = 1;

n2 = (a2 * 10 + b2) * 10 + c2;


}
}

int main()
{
setlocale(LC_ALL, "ru");

int n, n2;
cout << "Введите первое число " << endl;
cin >> n;
cout << "Введите второе число " << endl;
cin >> n2;

Foo1(&n, n2);

cout << "Первое число " << n << endl << "Второе число " << n2 << endl;

return 0;
}
Структура тест-кейса Пример
№ тест-кейса. Краткое описание 1 Анализ простой дроби
Предусловие (может Шаги:
отсутствовать) 1 Запустить программу
Описать, что должно быть выполнено до Ожидаемый результат
начала выполнения тест-кейса, например, число, у которого первая цифра в
заполнить список данными т. д. записи большее замениться 1, а у
Шаги
которого меньше - -1.
Перечислить последовательность
действий, какие конкретно данные ввести
в ответ на запрос программы. Фактический результат:
Ожидаемый результат выполнения
программы
Фактический результат выполнения
программы
Привести экранную форму из
работающей программы. Если совпадает
с ожидаемым результатом – тест
пройден.

Контрольные вопросы:

1) Программа на языке C++ состоит из функций, описаний и директив


препроцессора.
(Препроцессор — это программа, которая выполняет обработку
файла исходного кода перед началом компиляции).
Рассмотрим простейшую программу:
В первой строке с помощью директивы #include подключается заголовочный
файл <iostream>, который содержит необходимую информацию для
управления вводом/выводом.
Следующая директива using открывает доступ к пространству имен (англ.
namespace) std, в котором определяются средства стандартной библиотеки
языка C++.
Отправной точкой выполнения любой С++-программы является
функция main(). Функция содержит четыре элемента:
1) возвращаемый тип (в нашем случае int);
2) имя функции (main);
3) список параметров, заключенный в круглые скобки (в данном случае
список пуст);
4) заключенное в фигурные скобки, тело функции, представляющее собой
блок инструкций.

2) #include — вставляет текст из указанного файла


#define — задаёт макроопределение (макрос) или символическую
константу
#undef — отменяет предыдущее определение
#if — осуществляет условную компиляцию при истинности
константного выражения
#ifdef — осуществляет условную компиляцию при определённости
символической константы

3) Исходный код, разработанный и написанный на языке С или C++,


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

4) Тип данных определяет:

 представление данных в памяти компьютера;


 множество значений, которые могут принимать величины данного
типа;
 операции и функции, которые можно применять к величинам этого
типа.
Все типы языка C++ можно разделить на основные и составные. Основные
типы данных используются для представления целых, вещественных,
символьных и логических величин. К составным типам относятся массивы,
перечисления, функции, структуры, ссылки, указатели, объединения и
классы. Для описания основных типов данных определены следующие
ключевые слова:
 int (целый);
 char (символьный);
 wchar_t (расширенный символьный);
 bool (логический);
 float (вещественный);
 double (вещественный с двойной точностью).
Для уточнения диапазона значений и внутреннего представления
стандартных типов применяются четыре спецификатора типа:
 short (короткий);
 long (длинный);
 signed (знаковый);
 unsigned (беззнаковый).

5) Переменная — это именованная область памяти, в которой


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

Объявление переменных
Перед использованием любая переменная должна быть объявлена, т.е.
получить имя, тип и (необязательно) начальное значение. Общий формат
инструкции объявления переменных выглядит следующим образом:
 тип список_переменных, где
 элемент тип - это тип данных;
 элемент список_переменных - список имен переменных,
указанного типа.
Примеры объявления переменных:
 int i, k, x;
 double d, dBalance;
При объявлении, переменную можно инициализировать, т. е. присвоить ей
начальное значение, причем С++ позволяет выполнить динамическую
инициализацию с помощью любого выражения, действительного на момент
инициализации. Инициализатор можно записывать в двух формах:
 со знаком равенства: int a = 10, b = 20;
 в круглых скобках: int c (a+b);
Строка — последовательность (массив) символов. Если в
выражении встречается одиночный символ, он должен быть
заключен в одинарные кавычки. При использовании в выражениях
строка заключается в двойные кавычки. Признаком конца строки
является нулевой символ \0. В C++ строки можно описать с
помощью массива символов (массив элементов типа char), в
котором следует предусмотреть место для хранения признака
конца строки.
6) Т
7) int a; // объявление переменной a целого типа.
float b; // объявление переменной b типа данных с плавающей
запятой.
double c = 14.2; // инициализация переменной типа double.
char d = 's'; // инициализация переменной типа char.
bool k = true; // инициализация логической переменной k.
Заметьте, что в C++ оператор присваивания (=) — не является знаком
равенства и не может использоваться для сравнения значений. Оператор
равенства записывается как «двойное равно» — ==.
Присваивание используется для сохранения определенного значение в
переменной. Например, запись вида a = 10 задает переменной a значение
числа 10.
8) Описание объектов для управления вводом-выводом содержится в
файле iostream.h. При подключении этого файла с помощью
директивы #include <iostream.h> в программе автоматически
создаются виртуальные каналы связи cin для ввода с клавиатуры
и cout для вывода на экран, а также операции помещения в
поток << и чтения из потока >>.
С помощью объекта cin и операции >> можно присвоить значение
любой переменной. Например, если переменная x описана
как целочисленная, то команда cin>>x; означает, что в
переменную x будет записано некое целое число, введенное с
клавиатуры. Если необходимо ввести несколько переменных, то
следует написать cin>>x>>y>>z;.
Объект cout и операция << позволяет вывести на экран значение
любой переменной или текст. Текст необходимо заключать в двойные
кавычки. Запись cout<<x; означает вывод на экран значения
переменной x.

9) Операции делятся на унарные, бинарные и тернарную по количеству


участвующих в них операндов. Большинство стандартных операций может
быть переопределено (перегружено).Операции присваивания (=, +=, -=, *= и
т. д.)

Операции присваивания могут использоваться в программе как законченные


операторы.
Формат операции простого присваивания (=):

операнд_1 = операнд_2

Первый операнд должен быть L-значением, второй — выражением. Сначала


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

#includei
nt main()
{
int a = 3, b = 5, с = 7;
a = b; b = a; с = с + 1;
cout << "a = " << a;
cout << "\t b = " << b;
cout << "\t с = " << c;
return 0;}
Результат работы программы: a = 5 b = 5 c = 8.
10) Операторы управляют процессом выполнения программы. Набор
операторов языка С++ содержит все управляющие конструкции структурного
программирования.
Составной оператор ограничивается фигурными скобками. Все другие
операторы заканчиваются точкой с запятой.

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

 Составной оператор –  {...}

Действие составного оператора состоит в последовательном


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

 Оператор обработки исключений


try { <операторы> } catch (<объявление исключения>) {
<операторы> } catch (<объявление исключения>) { <операторы> } ...
catch (<объявление исключения>) { <операторы> }
 Условный оператор
if (<выражение>) <оператор 1> [else <оператор 2>]
 Оператор-переключатель
switch (<выражение>) { case <константное выражение 1>:
<операторы 1> case <константное выражение 2>: <операторы 2> ...
case <константное выражение N>: <операторы N> [default:
<операторы>] }

Оператор-переключатель предназначен для выбора одного из


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

 Оператор цикла с предусловием


while (<выражение>) <оператор>
 Оператор цикла с постусловием
do <оператор> while <выражение>;

В языке C++ этот оператор отличается от классической реализации


цикла с постусловием тем, что при истинности выражения происходит
продолжение работы цикла, а не выход из цикла.
 Оператор пошагового цикла
for ([<начальное выражение>]; [<условное выражение>];
[<выражение приращения>]) <оператор>

Тело оператора for выполняется до тех пор, пока условное


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

 Оператор цикла для диапазона


for (<элемент>: <массив>) <оператор>

Оператор цикла для диапазона предоставляет способ итерации по


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

 Оператор разрыва
break;

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


операторов while, do, for и switch. Он может содержаться только в теле
этих операторов. Управление передается оператору программы,
следующему за прерванным. Если оператор разрыва записан внутри
вложенных операторов while, do, for, switch, то он завершает только
непосредственно охватывающий его оператор.

 Оператор продолжения
continue;
Оператор продолжения передает управление на следующую итерацию
в операторах цикла while, do, for. Он может содержаться только в теле
этих операторов. В операторах do и while следующая итерация
начинается с вычисления условного выражения. В
операторе for следующая итерация начинается с вычисления
выражения приращения, а затем происходит вычисление условного
выражения.

 Оператор возврата
return [<выражение>];

Оператора возврата заканчивает выполнение функции, в которой он


содержится, и возвращает управление в вызывающую функцию.
Управление передается в точку вызывающей функции,
непосредственно следующую за оператором вызова.
Значение выражения, если она задано, вычисляется, приводится к
типу, объявленному для функции, содержащей оператор возврата, и
возвращается в вызывающую функцию. Если выражение опущено, то
возвращаемое функцией значение не определено.
11) Объявление массива имеет следующий синтаксис:
<спецификация типа> <имя> [<константное выражение>];
<спецификация типа> <имя> [ ];
Здесь квадратные скобки являются элементом синтаксиса, а не
признаком необязательности конструкции.
Объявление массива может иметь одну из двух синтаксических форм,
указанных выше. Квадратные скобки, следующие за именем, – признак того,
что переменная является массивом. Константное выражение, заключенное в
квадратные скобки определяет число элементов в массиве. Индексация
элементов массива в языке C++ начинается с нуля. Таким образом,
последний элемент массива имеет индекс на единицу меньше, чем число
элементов массива.
Во второй синтаксической форме константное выражение в квадратных
скобках опущено. Эта форма может быть использована, если в объявлении
массива присутствует инициализатор, либо массив объявляется как
формальный параметр функции, либо данное объявление является ссылкой
на объявление массива где-то в другом месте программы. Однако для
многомерного массива может быть опущена только первая размерность.
Многомерный массив, или массив массивов, объявляется путем задания
последовательности константных выражений в квадратных скобках,
следующей за именем:
<спецификация типа> <имя> [<константное выражение>][<константное
выражение>] ... ;
Каждое константное выражение определяет количество элементов в
данном измерении массива, поэтому объявление двумерного массива
содержит два константных выражение, трехмерного – три и т.д.
Массив может состоять из элементов любого типа, кроме типа void и
функций, т.е. элементы массива могут
иметь базовый, перечислимый, структурный тип,
быть объединением, указателем или массивом.
12) Массив — это набор элементов, хранящихся в постоянных ячейках
памяти.
Структура — это определенный пользователем тип данных в C / C ++.
Структура создает тип данных, который можно использовать для
группировки элементов, возможно, разных типов в один тип.
13)
Функция определяет действия, которые выполняет программа. Функции
позволяют выделить набор инструкций и придать ему имя. А затем
многократно по присвоенному имени вызывать в различных частях
программы. По сути функция - это именованный блок кода.
Формальное определение функции выглядит следующим образом:
1 тип имя_функции(параметры)
2 {
3     инструкции
4 }

Для выполнения функции ее необходимо вызвать. Вызов функции осуществляется в


форме:

имя_функции(аргументы);

Объявление функции еще называют прототипом. Формальное объявление выглядит


следующим образом:

тип имя_функции(параметры);
14) Называйте функцию/переменную/структуру/класс так, чтобы было
понятно что он/она выполняет, какую роль играет и за что отвечает.

15) Передача параметров выполняется следующим образом. Вычисляются


выражения, стоящие на месте фактических параметров. Затем формальным
параметрам присваиваются значения фактических. Выполняется проверка
типов и при необходимости выполняется их преобразование. Возврат
результата из функции в вызывающую ее функцию осуществляется
оператором
return (значение);
Работает оператор так. Вычисляется значение выражения, указанного
после return и преобразуется к типу возвращаемого функцией значения.
Выполнение функции завершается, а вычисленное значение передается в
вызывающую функцию. Любые операторы, следующие в функции за
оператором return, игнорируются. Программа продолжает свою работу с
оператора следующего за оператором вызова данной функции.

16) Прототип и описание функции используются компилятором для того,


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

17) Указатель — это переменная. Такая же, как и любая другая. У нее есть
свое значение и свой адрес в памяти.

Ссылка — это указатель, с которым можно работать, как с обычной


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

18) Статическое (фиксированное) выделение памяти. В этом случае память


выделяется только один раз во время компиляции. Размер выделенной
памяти есть фиксированным и неизменным до конца выполнения
программы. Примером такого выделения может служить объявление массива
из 10 целых чисел:
int M[10]; // память для массива выделяется один раз, размер памяти
фиксированный
 Динамическое выделение памяти. В этом случае используется комбинация
операторов new и delete. Оператор new выделяет память для переменной
(массива) в специальной области памяти, которая называется «куча» (heap).
Оператор delete освобождает выделенную память. Каждому
оператору new должен соответствовать свой оператор delete.

19) Функция, которой передается управление после запуска программы,


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

// без параметров:

тип main()

{ /* ... */}
// с двумя параметрами:

тип main(int argc, char* argv[])

{ /* ... */}

При запуске программы из командной строки параметры разделяются


пробелами. Имена параметров в программе могут быть любыми, но принято
использовать argc и argv. Первый параметр argc определяет количество
параметров, передаваемых функции, включая имя самой программы, второй
параметр argv является указателем на массив указателей типа char*. Каждый
элемент массива содержит указатель на отдельный параметр командной
строки, хранящийся в виде С-строки, оканчивающейся нуль-символом.
Первый элемент массива argv[0] ссылается на полное имя запускаемого на
выполнение файла, следующий argv[l] указывает на первый параметр, argv[2]
– на второй параметр, и так далее. Параметр argv[argc] должен быть равен 0.

Параметры функции main () служат для передачи программе аргументов


командной строки, т. е. имен файлов, ключей, опций и вообще всего, что вы
вводите с клавиатуры после подсказки DOS, запуская программу. Конечно,
программа не обязана воспринимать какие-либо команды, указываемые в
строке запуска, однако в любом случае функции main () передаются два
параметра – число аргументов/включая имя, под которым запущена
программа (argc), и массив указателей (argv) на отдельные аргументы
(выделенные элементы командной строки).

Вам также может понравиться