Python, Pascal или C: какой язык выбрать? Примеры и советы

Раздел: Основы Python -> Сравнение языков программирования

В этой статье сравниваются языки Python, Pascal и C на примере решения типовых задач. Рассматриваются различные подходы к вычислению суммы чисел от 1 до N, их сильные и слабые стороны.

Основное решение: итеративный цикл

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

Python

def sum_n_iter(n):
    total = 0
    for i in range(1, n+1):
        total += i
    return total

print(sum_n_iter(10))

программа python pascal c (сравнение python, pascal и c)

55

Pascal

program sum_iter;
var
  n, i, total: integer;
begin
  n := 10;
  total := 0;
  for i := 1 to n do
    total := total + i;
  writeln(total);
end.
55

C

#include <stdio.h>

int sum_iter(int n) {
    int total = 0;
    for (int i = 1; i <= n; i++) {
        total += i;
    }
    return total;
}

int main() {
    printf("%d\n", sum_iter(10));
    return 0;
}
55

Пояснение:

Цикл выполняется N раз, на каждом шаге к переменной total прибавляется текущее значение i. В Python используется range, в Pascal - for to, в C - классический for с инкрементом.

Как вычислить сумму с помощью рекурсии?

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

# Python
def sum_rec(n):
    if n == 0:
        return 0
    return n + sum_rec(n-1)

print(sum_rec(10))
55
// Pascal
program sum_rec;
function sum(n: integer): integer;
begin
  if n = 0 then
    sum := 0
  else
    sum := n + sum(n-1);
end;
begin
  writeln(sum(10));
end.
55
// C
int sum_rec(int n) {
    if (n == 0)
        return 0;
    return n + sum_rec(n-1);
}

Типичная ошибка:

Для N=100000 рекурсия вызовет переполнение стека в C и Python (если не увеличено ограничение). В Pascal также возможно переполнение. Решение - использовать итеративный метод или хвостовую рекурсию (не поддерживается без оптимизации).

Цель: демонстрация рекурсивного мышления, удобна для малых N.

Как использовать формулу арифметической прогрессии для мгновенного вычисления?

Формула суммы первых N натуральных чисел: S = N*(N+1)/2. Этот метод работает за O(1), но может вызвать целочисленное переполнение в C и Pascal (при больших N).

# Python
def sum_formula(n):
    return n * (n + 1) // 2

print(sum_formula(10))
55
// Pascal
program sum_formula;
var n: integer;
begin
  n := 10;
  writeln(n * (n + 1) div 2);
end.
55
// C
int sum_formula(int n) {
    return n * (n + 1) / 2;
}

Проблема переполнения:

В C и Pascal при n=50000 результат войдет в 32-битный int (1250025000 < 2^31-1), но при n=100000 результат 5000050000 уже превышает 2^31-1. В Python целые числа неограниченны, ошибка не возникнет. Решение: использовать тип long long в C, int64 в Pascal, либо проверять диапазон.

Цель: максимальная производительность, когда диапазон N известен и безопасен.

Как упростить код с помощью встроенных средств (только Python)?

Python предлагает встроенную функцию sum и генератор range. Это самый лаконичный способ.

def sum_builtin(n):
    return sum(range(1, n+1))

print(sum_builtin(10))
55

Аналог в Pascal или C отсутствует, требуется написание собственного цикла. Цель: быстрая запись при удобстве, но функция sum всё равно выполняет цикл.

Как обрабатывать пользовательский ввод и проверять корректность данных?

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

# Python
try:
    n = int(input("Введите N: "))
    if n <= 0:
        print("Ошибка: число должно быть положительным")
    else:
        print("Сумма:", sum_formula(n))
except ValueError:
    print("Ошибка: введите целое число")
(пример ввода 10)
Сумма: 55
// Pascal
program input_sum;
var
  n: integer;
begin
  write('Введите N: ');
  readln(n);
  if n <= 0 then
    writeln('Ошибка: число должно быть положительным')
  else
    writeln('Сумма: ', n*(n+1) div 2);
end.
// C
#include <stdio.h>
int main() {
    int n;
    printf("Введите N: ");
    if (scanf("%d", &n) != 1 || n <= 0) {
        printf("Ошибка ввода\n");
        return 1;
    }
    printf("Сумма: %d\n", n*(n+1)/2);
    return 0;
}

Типичные ошибки:

В C необработанный ввод (буквы) может вызвать бесконечный цикл; в Pascal readln без проверки; в Python требуется блок try. Решение: использовать проверки возвращаемого значения (scanf), читать строки и парсить.

Цель: создание устойчивых к некорректному вводу программ.

Расширенный пример: сортировка массива методом пузырька

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

Python

Пример
def bubble_sort(arr):
    n = len(arr)
    for i in range(n):
        swapped = False
        for j in range(0, n-i-1):
            if arr[j] > arr[j+1]:
                arr[j], arr[j+1] = arr[j+1], arr[j]
                swapped = True
        if not swapped:
            break
    return arr

# Чтение из файла
with open('input.txt', 'r') as f:
    data = list(map(int, f.read().split()))

sorted_data = bubble_sort(data)
print('Отсортированный массив:', sorted_data)

# Запись в файл
with open('output.txt', 'w') as f:
    f.write(' '.join(map(str, sorted_data)))
input.txt: 5 3 8 1 2
output.txt: 1 2 3 5 8

Pascal

Пример
program bubble_sort;
const MAX_SIZE = 100;
type arr_type = array[1..MAX_SIZE] of integer;
var
  arr: arr_type;
  n, i, j, tmp: integer;
  swapped: boolean;
  f: text;
begin
  assign(f, 'input.txt');
  reset(f);
  n := 0;
  while not eof(f) do begin
    n := n + 1;
    read(f, arr[n]);
  end;
  close(f);

  for i := 1 to n-1 do begin
    swapped := false;
    for j := 1 to n-i do begin
      if arr[j] > arr[j+1] then begin
        tmp := arr[j];
        arr[j] := arr[j+1];
        arr[j+1] := tmp;
        swapped := true;
      end;
    end;
    if not swapped then break;
  end;

  assign(f, 'output.txt');
  rewrite(f);
  for i := 1 to n do
    write(f, arr[i], ' ');
  close(f);
end.

C

Пример
#include <stdio.h>
#include <stdlib.h>

void bubble_sort(int *arr, int n) {
    int swapped;
    for (int i = 0; i < n - 1; i++) {
        swapped = 0;
        for (int j = 0; j < n - i - 1; j++) {
            if (arr[j] > arr[j+1]) {
                int temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
                swapped = 1;
            }
        }
        if (!swapped) break;
    }
}

int main() {
    FILE *fin = fopen("input.txt", "r");
    if (!fin) return 1;
    int *arr = NULL, n = 0, cap = 10;
    arr = malloc(cap * sizeof(int));
    while (fscanf(fin, "%d", &arr[n]) == 1) {
        n++;
        if (n >= cap) {
            cap *= 2;
            arr = realloc(arr, cap * sizeof(int));
        }
    }
    fclose(fin);

    bubble_sort(arr, n);

    FILE *fout = fopen("output.txt", "w");
    for (int i = 0; i < n; i++)
        fprintf(fout, "%d ", arr[i]);
    fclose(fout);
    free(arr);
    return 0;
}

Типичные трудности:

В C необходимо динамически управлять памятью (malloc/realloc/free). В Pascal размер массива фиксированный (MAX_SIZE), что ограничивает входные данные. В Python работа с файлами и списками проще, но скорость сортировки ниже при больших объёмах.

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

Нестандартный пример: сортировка с использованием указателей на функции (C)

Пример
#include <stdio.h>
#include <stdlib.h>

typedef int (*cmp_func)(int, int);

int ascending(int a, int b) { return a > b; }
int descending(int a, int b) { return a < b; }

void bubble_sort_gen(int *arr, int n, cmp_func cmp) {
    for (int i = 0; i < n-1; i++) {
        int swapped = 0;
        for (int j = 0; j < n-i-1; j++) {
            if (cmp(arr[j], arr[j+1])) {
                int temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
                swapped = 1;
            }
        }
        if (!swapped) break;
    }
}

int main() {
    int arr[] = {5, 3, 8, 1, 2};
    int n = sizeof(arr)/sizeof(arr[0]);
    bubble_sort_gen(arr, n, ascending);
    for (int i = 0; i < n; i++) printf("%d ", arr[i]);
    printf("\n");
    bubble_sort_gen(arr, n, descending);
    for (int i = 0; i < n; i++) printf("%d ", arr[i]);
    printf("\n");
    return 0;
}
1 2 3 5 8
8 5 3 2 1

Этот пример демонстрирует гибкость C через указатели на функции: одна и та же процедура сортировки может работать с разными критериями сравнения без дублирования кода. В Python подобное достигается передачей lambda-функции в параметр key, в Pascal - процедурными типами, но синтаксис более громоздкий.

Цель: показать возможности метапрограммирования и повторного использования кода в C.

Сравнение Python, Pascal и C - comments

En
программа python pascal c (python)