Перейти к содержанию

Лекция 2: Основные этапы решения задач на ЭВМ

Природа больше любит женщин, а мужчины - расходный материал.


Введение

Программирование - процесс создания и модификации программ.

Программы = алгоритмы + структуры данных

Цель программирования - описание процесса обработки информации.

Данные - формализованное представление фактов.

Информация — осмысленное представление данных.

Знания — обработанная информация, используемая для принятия решений.


Основные этапы решения задач на ЭВМ

  1. Постановка задачи: Определение целей и требований.
  2. Анализ и исследование: Изучение методов решения.
  3. Разработка математической модели: Формулировка задачи через уравнения.
  4. Проектирование алгоритма: Разработка последовательности действий.
  5. Программирование: Написание кода.
  6. Тестирование и отладка: Проверка и исправление ошибок.
  7. Эксплуатация и сопровождение: Внедрение и поддержка.
  8. Анализ результатов: Оценка точности результатов.

Классификация языков программирования

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

По парадигме программирования

  • Императивные языки: Основаны на последовательности команд, изменяющих состояние программы (например, C).
  • Декларативные языки: Основаны на описании желаемого результата, а не на последовательности действий (например, SQL).
  • Функциональные языки: Основаны на применении функций, избегая изменяемых состояний (например, Haskell).
  • Объектно-ориентированные языки: Основаны на концепции объектов и классов (например, Java, C++).
  • Логические языки: Основаны на формальной логике (например, Prolog).

По назначению

  • Системные языки: Разработаны для системного программирования (например, C, Rust).
  • Прикладные языки: Предназначены для решения конкретных задач (например, MATLAB, R).
  • Сценарные языки: Разработаны для написания скриптов (например, Bash, Perl).

По степени типизации

  • Строго типизированные языки: Требуют явного указания типов данных (например, Java).
  • Слабо типизированные языки: Допускают неявные преобразования типов (например, JavaScript).

По времени компиляции

  • Компилируемые языки: Код компилируется в машинный код до выполнения (например, C).
  • Интерпретируемые языки: Код выполняется интерпретатором на лету (например, Python).

По кроссплатформенности

  • Кроссплатформенные языки: Поддерживаются на нескольких операционных системах (например, Java, Python).

По уровню абстракции

  • Низкоуровневые языки: Близки к машинному коду (например, ассемблер).
  • Высокоуровневые языки: Обеспечивают высокий уровень абстракции, удобный для человека (например, Python, Java).

Алгоритм и его свойства

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

  1. Определенность: Алгоритм должен быть однозначным.
  2. Результативность: Алгоритм должен приводить к результату.
  3. Массовость: Алгоритм должен решать класс задач.
  4. Дискретность: Алгоритм состоит из конечного числа шагов.

Способы записи алгоритмов:

  • Вербальный: Запись на естественном языке.
  • Формульно-словесный: Использование формул и текста.
  • Графический: Блок-схемы, диаграммы.
  • Алгоритмический язык: Язык, специально разработанный для записи алгоритмов (например, псевдокод).
  • UML-диаграммы: Используются для представления системы или процесса.

Типы вычислительных процессов:

  1. Линейный алгоритм: Последовательное выполнение действий.
  2. Ветвящийся алгоритм: Действия зависят от условий (например, нахождение корней квадратного уравнения).
  3. Циклический алгоритм: Повторение действий (например, вычисление значений функции для диапазона значений).

Примеры реализации алгоритмов на C

Пример линейного алгоритма на C

#include <stdio.h>

int main() {
    double a = 5.0, b = 3.0, result;
    result = a * b;
    printf("Result: %.2lf\n", result);
    return 0;
}

Пример разветвляющегося алгоритма на C (нахождение корней квадратного уравнения)

#include <stdio.h>
#include <math.h>

int main() {
    double a, b, c, discriminant, root1, root2;
    printf("Enter coefficients a, b, and c: ");
    scanf("%lf %lf %lf", &a, &b, &c);
    discriminant = b * b - 4 * a * c;

    if (discriminant > 0) {
        root1 = (-b + sqrt(discriminant)) / (2 * a);
        root2 = (-b - sqrt(discriminant)) / (2 * a);
        printf("Roots are: %.2lf and %.2lf\n", root1, root2);
    } else if (discriminant == 0) {
        root1 = -b / (2 * a);
        printf("Root is: %.2lf\n", root1);
    } else {
        printf("No real roots.\n");
    }
    return 0;
}
Важный нюанс при компиляции с <math.h> в Linux и FreeBSD

При компиляции программы на C, использующей <math.h>, на Linux и FreeBSD необходимо указывать флаг -lm, иначе возникнут ошибки линковки. Это связано с тем, что в этих ОС математическая библиотека (libm) отделена от стандартной библиотеки C и требует явного подключения. На Windows это не требуется, так как libm встроена в стандартную библиотеку.

gcc -Wall -g -o example.out 1.c **-lm**

Пример циклического алгоритма на C (вычисление значений функции)

#include <stdio.h>

int main() {
    int x;
    double b = 5.0, result;

    for (x = -10; x <= 10; x += 2) {
        result = x * x + b;
        printf("f(%d) = %.2f\n", x, result);
    }
    return 0;
}

I've got a bike, you can ride it if you like