theme changed

This commit is contained in:
nik
2025-09-30 08:21:09 +03:00
parent 4c261f7def
commit 8bd93df2ae
917 changed files with 15023 additions and 0 deletions

549
labs/lab3/report.typ Normal file
View File

@@ -0,0 +1,549 @@
#set text(size: 1.3em)
#show raw.where(block: false): box.with(
fill: luma(240),
inset: (x: 3pt, y: 0pt),
outset: (y: 3pt),
radius: 2pt,
)
#show raw.where(block: true): block.with(
fill: luma(240),
inset: 10pt,
radius: 4pt,
)
// title
#align(center)[Санкт-Петербургский национальный исследовательский университет информационных технологий, механики и оптики]
\
\
\
#align(center)[Факультет инфокоммуникационных технологий]
#align(center)[Направление подготовки 11.03.02]
\
\
#align(center)[Лабораторная работа №3]
#align(center)[Использование выражений]
\
\
\ //#align(center)[Вариант 19]
\
\
\
\
\
\
\
#align(right)[Выполнил:]
#align(right)[Дощенников Никита Андреевич]
#align(right)[Группа: К3221]
#align(right)[Проверил:]
#align(right)[Иванов Сергей Евгеньевич]
\
\
#align(center)[Санкт-Петербург]
#align(center)[2025]
#pagebreak()
=== Цель работы:
Изучить и приобрести навыки использования управляющих конструкций для организации вычислений.
=== Упражнение 1. Реализация операторов выбора.
==== Задание 1. Применение конструкции if-else-if.
В этом задании я составил программу, которая выдает одно из сообщений "внутри", "вне" или "на границе" в зависимости от положения точки относительно заштрихованной области на графике, представленном на рисунке.
#align(center)[#image("assets/1.png")]
```cs
using System;
public class Program
{
static void Main(string[] args)
{
Console.Write("x = ");
float x = float.Parse(Console.ReadLine());
Console.Write("y = ");
float y = float.Parse(Console.ReadLine());
if (x * x + y * y < 9 && y > 0)
{
Console.WriteLine("внутри");
}
else if (x * x + y * y > 9 || y < 0)
{
Console.WriteLine("вне");
}
else
{
Console.WriteLine("на границе");
}
}
}
```
Пример работы:
#align(center)[#image("assets/2.png")]
#align(center)[#image("assets/3.png")]
#align(center)[#image("assets/4.png")]
==== Задание 2. Применение оператора switch.
Я создал программу моделирующую работу калькулятора. Пользователем вводится первый операнд, требуемую операцию и второй операнд. Затем производится расчет результата.
```cs
using System;
public class Program
{
static void Main(string[] args)
{
Console.Write("A = ");
double a = double.Parse(Console.ReadLine());
Console.Write("OP = ");
char op = char.Parse(Console.ReadLine());
Console.Write("B = ");
double b = double.Parse(Console.ReadLine());
bool ok = true;
double res = 0;
switch (op)
{
case '+': res = a + b; break;
case '-': res = a - b; break;
case '*': res = a * b; break;
case '/':
case ':':
res = a / b; break;
default: ok = false; break;
}
if (ok)
{
Console.WriteLine("{0} {1} {2} = {3}", a, op, b, res);
}
else
{
Console.WriteLine("Операция не определена");
}
}
}
```
Пример работы:
1) c правильными значениями:
#align(center)[#image("assets/5.png")]
2) при делении на нуль:
#align(center)[#image("assets/6.png")]
Бесконечность, так как в стандарте IEEE-754 прописан такой результат.
3) при делении нуль на нуль:
#align(center)[#image("assets/7.png")]
NaN, опять же в соответствии со стандартом.
4) при неправильной операции:
#align(center)[#image("assets/8.png")]
Мы проваливаемся к значению по умолчанию.
==== Задание 3. Определение високосного года.
Программа, по введенному натуральному числу, определяет, является ли год с номером, равным этому числу, високосным.
```cs
using System;
public class Program
{
public static void Main(string[] args)
{
Console.WriteLine("input a year: ");
int year = int.Parse(Console.ReadLine());
if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
{
Console.WriteLine("YES");
}
else
{
Console.WriteLine("NO");
}
}
}
```
Пример работы:
#align(center)[#image("assets/9.png")]
#align(center)[#image("assets/10.png")]
=== Упражнение 2. Реализация циклов при работе с данными размерных типов.
==== Задание 1. Использование операторов цикла while, do while и for.
Я написал программу, которая выводит на экран последовательность целых нечетных чисел в строчку через пробел с помощью трех операторов цикла `while`, `do while` и `for`.
```cs
using System;
public class Program
{
public static void Main(string[] args)
{
Console.Write("n = ");
int n = int.Parse(Console.ReadLine());
// while
Console.Write("\nwhile: \t\t");
int i = 1;
while (i <= n)
{
Console.Write(" " + i);
i += 2;
}
// do-while
Console.Write("\ndo while: \t");
i = 1;
do
{
Console.Write(" " + i);
i += 2;
}
while (i <= n);
// for:
Console.Write("\nfor: \t\t");
for (i = 1; i<=n; i+=2)
{
Console.Write(" " + i);
}
}
}
```
Пример работы:
#align(center)[#image("assets/11.png")]
Была написана программа, которая печатает таблицу синусов и их аргументов с периодом 0.01 от `x1` до `x2`.
```cs
using System;
public class Program
{
static void Main(string[] args)
{
double x, x1, x2, y;
Console.WriteLine("input x1:");
x1 = double.Parse(Console.ReadLine());
Console.WriteLine("input x2:");
x2 = double.Parse(Console.ReadLine());
Console.WriteLine("x\t\t sin(x)");
Console.WriteLine("--------------------------");
x = x1;
do
{
y = Math.Sin(x);
Console.WriteLine($"{x:F2}\t {y:F6}");
x = x + 0.01;
}
while (x <= x2);
}
}
```
Пример работы:
#align(center)[#image("assets/12.png")]
```cs
using System;
using System.Globalization;
class Program
{
static void FuncWhile()
{
var ci = CultureInfo.InvariantCulture;
double x1 = double.Parse(Console.ReadLine(), ci);
double x2 = double.Parse(Console.ReadLine(), ci);
double h = double.Parse(Console.ReadLine(), ci);
double x = x1;
while (x <= x2 + 1e-12)
{
double y = Math.Sin(x);
Console.WriteLine($"while: {x.ToString(ci)} {y.ToString(ci)}");
x += h;
}
}
static void FuncDoWhile()
{
var ci = CultureInfo.InvariantCulture;
double x1 = double.Parse(Console.ReadLine(), ci);
double x2 = double.Parse(Console.ReadLine(), ci);
double h = double.Parse(Console.ReadLine(), ci);
double x = x1;
if (h <= 0) return;
do
{
double y = Math.Sin(x);
Console.WriteLine($"do-while: {x.ToString(ci)} {y.ToString(ci)}");
x += h;
} while (x - h < x2 + 1e-12);
}
static int GcdWhile(int a, int b)
{
a = Math.Abs(a);
b = Math.Abs(b);
while (b != 0)
{
int temp = a % b;
a = b;
b = temp;
}
return a;
}
static int GcdDoWhile(int a, int b)
{
a = Math.Abs(a);
b = Math.Abs(b);
int temp;
if (b == 0) return a;
do
{
temp = a % b;
a = b;
b = temp;
} while (b != 0);
return a;
}
static void Main()
{
Console.WriteLine("=== Функция с while ===");
FuncWhile();
Console.WriteLine("=== Функция с do-while ===");
FuncDoWhile();
Console.WriteLine("Введите два числа для НОД (while):");
int a = int.Parse(Console.ReadLine());
int b = int.Parse(Console.ReadLine());
Console.WriteLine($"НОД (while): {GcdWhile(a, b)}");
Console.WriteLine("Введите два числа для НОД (do-while):");
a = int.Parse(Console.ReadLine());
b = int.Parse(Console.ReadLine());
Console.WriteLine($"НОД (do-while): {GcdDoWhile(a, b)}");
}
}
```
- *while* подходит, когда важно проверять условие до входа в цикл (может выполниться 0 раз).
- *do…while* удобен, когда тело должно выполниться минимум один раз.
- Для функций на интервале *do…while* проще гарантирует вывод крайней точки.
- Для алгоритма Евклида оба варианта дают одинаковый результат; *while* короче, *do…while* более наглядно выражает шаг алгоритма.
==== Задание 2. Расчет суммы, используя операторы перехода.
Составлена программа, которая реализует сумму
$
s = sum_(i = 1)^(100) i,
$
для $i$, находящихся от $1$ до $k$ и от $m$ до $100$.
```cs
using System;
class Program
{
static void Main()
{
Console.Write("Введите k: ");
int k = int.Parse(Console.ReadLine());
Console.Write("Введите m: ");
int m = int.Parse(Console.ReadLine());
int s = 0;
for (int i = 1; i <= 100; i++)
{
if (i > k && i < m) continue;
s += i;
}
Console.WriteLine("Сумма = " + s);
}
}
```
Пример работы:
#align(center)[#image("assets/13.png")]
==== Задание 3. Стрельба по мишени.
Разработа программа, имитирующая стрельбу по мишени.
```cs
using System;
class Program
{
static int VariantFromStudentNumber(int n) => (n % 2 != 0) ? 1 : 2;
static int ScoreVariant1(double x, double y)
{
var r = Math.Sqrt(x * x + y * y);
if (r <= 1) return 10;
if (r <= 2) return 5;
if (r <= 3) return 2;
return 0;
}
static int Sector(double x, double y)
{
var a = Math.Atan2(y, x);
if (a > Math.PI / 4 && a <= 3 * Math.PI / 4) return 1;
if (a > -Math.PI / 4 && a <= Math.PI / 4) return 5;
if (a > -3 * Math.PI / 4 && a <= -Math.PI / 4) return 2;
return 3;
}
static int ScoreVariant2(double x, double y)
{
var r = Math.Sqrt(x * x + y * y);
if (r <= 1) return 10;
if (r <= 3) return Sector(x, y);
return 0;
}
static void Main()
{
Console.Write("Номер по списку: ");
int student = int.Parse(Console.ReadLine());
int variant = VariantFromStudentNumber(student);
Console.Write("Сколько выстрелов: ");
int n = int.Parse(Console.ReadLine());
Console.Write("Случайный центр? (y/n): ");
bool rndCenter = Console.ReadLine().Trim().ToLower() == "y";
Console.Write("Случайная помеха? (y/n): ");
bool noise = Console.ReadLine().Trim().ToLower() == "y";
var rnd = new Random();
double cx = 0, cy = 0;
if (rndCenter)
{
cx = rnd.NextDouble() * 2 - 1;
cy = rnd.NextDouble() * 2 - 1;
}
int sum = 0;
for (int i = 0; i < n; i++)
{
Console.Write($"Выстрел {i + 1} (x y): ");
var parts = Console.ReadLine().Trim().Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
double x = double.Parse(parts[0]);
double y = double.Parse(parts[1]);
if (noise)
{
x += (rnd.NextDouble() * 0.2 - 0.1);
y += (rnd.NextDouble() * 0.2 - 0.1);
}
x -= cx;
y -= cy;
int s = variant == 1 ? ScoreVariant1(x, y) : ScoreVariant2(x, y);
sum += s;
Console.WriteLine($"Очки: {s}, сумма: {sum}");
}
Console.WriteLine($"Итоговая сумма: {sum}");
}
}
```
Пример работы:
#align(center)[#image("assets/14.png")]
=== Code review. (by #link("https://zzzcode.ai")[zzzcode.ai])
*Резюме*
Код выполняет несколько задач, включая определение положения точки относительно круга, выполнение арифметических операций, проверку високосного года, вывод чисел и вычисление НОД. Однако, в коде присутствуют некоторые недостатки, которые могут быть улучшены для повышения его качества и удобства использования.
*Ошибка*
В коде отсутствует обработка исключений при парсинге пользовательского ввода. Это может привести к сбоям программы, если пользователь введет некорректные данные. Рекомендуется использовать TryParse для безопасного парсинга.
*Стиль кода*
Стиль кода в целом соответствует стандартам C\#. Однако, в некоторых местах можно улучшить читаемость, добавив комментарии и более описательные имена переменных. Например, вместо `x1`, `x2` можно использовать `startX`, `endX`.
*Структура кода*
Код разбит на несколько классов, что хорошо для организации. Однако, каждый класс содержит метод `Main`, что не является хорошей практикой. Рекомендуется создать один класс с единственным методом `Main`, а остальные функции вынести в отдельные методы.
`Читаемость`
Читаемость кода можно улучшить, добавив комментарии, объясняющие логику выполнения. Также стоит использовать более понятные имена переменных и методов, чтобы другие разработчики могли быстрее понять, что делает код.
`Производительность`
Код выполняется достаточно быстро для небольших входных данных. Однако, в случае больших объемов данных, стоит рассмотреть возможность оптимизации, например, путем использования более эффективных алгоритмов.
Масштабируемость
Код не очень масштабируем, так как он жестко привязан к конкретным задачам. Рекомендуется использовать более модульный подход, чтобы можно было легко добавлять новые функции без изменения существующего кода.
`Безопасность`
Безопасность кода можно улучшить, добавив обработку исключений и проверку входных данных. Это поможет избежать потенциальных уязвимостей, связанных с некорректным вводом.
`Обработка ошибок`
Обработка ошибок в коде отсутствует. Рекомендуется использовать конструкции `try-catch` для обработки возможных исключений, особенно при работе с пользовательским вводом и парсингом данных.
*Заключение*
В целом, код выполняет свои функции, но требует улучшений в области обработки ошибок, читаемости и структуры. Рекомендуется внести изменения, чтобы сделать код более безопасным, масштабируемым и удобным для чтения.
=== Выводы.
В ходе проделанной работы, я изучил и приобрел навыки использования управляющих конструкций для организации вычислений.