Представьте себе: 1972 год, клёш в самом разгаре, и где-то в священных залах Bell Labs блестящий ум по имени Деннис Ритчи случайно создаёт один из самых влиятельных языков программирования в истории. Он и подумать не мог, что его «простой» язык системного программирования станет родоначальником бесчисленного количества современных языков программирования и основой всего: от операционной системы вашего смартфона до серверов, обеспечивающих работу ваших любимых сайтов.

Скромные начала: когда B было недостаточно

История языка C начинается не с самого C, а с генеалогического древа, больше похожего на мыльную оперу программирования. Наш рассказ начинается с ALGOL 1960 года, который представил революционную концепцию структурного программирования. Затем появился BCPL (Basic Combined Programming Language) в 1967 году, разработанный Мартином Ричардсом, за ним последовал язык B, созданный Кеном Томпсоном в 1970 году. Но вот где всё становится интереснее: B был бестипным, что звучит круто в теории, но было примерно так же практично, как строить небоскрёб из пластилина. Деннис Ритчи, работая вместе с командой разработчиков Unix в Bell Labs, понял, что им нужно что-то более надёжное, более мощное и, честно говоря, более типизированное.

graph TD A[ALGOL 1960] --> B[BCPL 1967] B --> C[B Language 1970] C --> D[C Language 1972] D --> E[ANSI C 1989] E --> F[C99 1999] F --> G[C11 2011] D --> H[C++] D --> I[Java] D --> J[Python] D --> K[JavaScript] style D fill:#ff6b6b style E fill:#4ecdc4 style F fill:#45b7d1 style G fill:#96ceb4

Рождение легенды: 1972 год

В 1972 году Деннис Ритчи начал разработку C как языка реализации системы для новой операционной системы Unix. Время было выбрано идеально — Bell Labs выводила из эксплуатации амбициозный, но в конечном итоге чрезмерно разрекламированный проект Multics, и команде было нужно что-то компактное, эффективное и способное перестроить Unix с нуля. К 1973 году волшебство произошло. Операционная система Unix была переписана на C, доказав, что этот новый язык был не просто очередным академическим упражнением — он был готов к производству и достаточно мощным для серьёзного системного программирования.

Ключевые особенности, которые сделали C настоящим переломным моментом

Управление памятью низкого уровня: мечта человека, одержимого контролем

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

#include <stdio.h>
#include <stdlib.h>
int main() {
    // Прямое выделение памяти — здесь главный вы
    int *numbers = (int*)malloc(5 * sizeof(int));
    if (numbers == NULL) {
        printf("Ошибка выделения памяти!\n");
        return 1;
    }
    // Заполняем выделенную память
    for (int i = 0; i < 5; i++) {
        numbers[i] = i * i;
        printf("numbers[%d] = %d\n", i, numbers[i]);
    }
    // Убирайтесь за собой — у C нет службы горничных
    free(numbers);
    return 0;
}

Структурированное программирование: приведение порядка в хаос

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

#include <stdio.h>
// Функция для вычисления факториала — модульная и переиспользуемая
int factorial(int n) {
    if (n <= 1) return 1;
    return n * factorial(n - 1);
}
// Функция для проверки, является ли число простым
int is_prime(int num) {
    if (num < 2) return 0;
    for (int i = 2; i * i <= num; i++) {
        if (num % i == 0) return 0;
    }
    return 1;
}
int main() {
    int number = 7;
    printf("Факториал числа %d: %d\n", number, factorial(number));
    printf("%d является %s\n", number, is_prime(number) ? "простым" : "не простым");
    return 0;
}

Стандартизация: от хаоса к порядку

Популярность C привела к тому, что мы могли бы назвать «диким западом» языков программирования — у каждого была своя версия, свои особенности и своё толкование того, каким должен быть C. Это было примерно так же устойчиво, как пытаться согнать кошек с завязанными глазами. На помощь пришёл ANSI (Американский национальный институт стандартов) в 1983 году, создав комитет X3J11 для установления официального стандарта C. К 1989 году появился ANSI C (также известный как C89), который позже был признан ISO как ISO/IEC 9899-1990.

Хронология эволюции

C89/C90: первая стандартизированная версия — представьте её как праздник совершеннолетия C C99: добавлены встроенные функции, массивы переменной длины и однострочные комментарии (// стиль) C11: представлена поддержка многопоточности и другие современные функции Давайте посмотрим на многопоточность C11 в действии:

#include <stdio.h>
#include <threads.h>
#include <unistd.h>
int worker_function(void *arg) {
    int id = *(int*)arg;
    for (int i = 0; i < 5; i++) {
        printf("Поток %d: работает... %d\n", id, i);
        thrd_sleep(&(struct timespec){.tv_sec=1}, NULL);
    }
    return 0;
}
int main() {
    thrd_t threads;
    int thread_ids = {1, 2, 3};
    // Создаём потоки
    for (int i = 0; i < 3; i++) {
        if (thrd_create(&threads[i], worker_function, &thread_ids[i]) != thrd_success) {
            printf("Не удалось создать поток %d\n", i);
            return 1;
        }
    }
    // Ждём завершения всех потоков
    for (int i = 0; i < 3; i++) {
        thrd_join(threads[i], NULL);
    }
    printf("Все потоки завершены!\n");
    return 0;
}

Эффект ряби: как C повлиял на современное программирование

C не просто создал язык программирования — он создал династию программирования. Влияние C на современные языки программирования похоже на наблюдение мастер-класса по теме «Как запустить тысячу кораблей».

graph LR C[C Language] --> CPP[C++
Объектно-ориентированный] C --> Java[Java
Независимый от платформы] C --> CSharp[C#
Ответ Microsoft] C --> Go[Go
Современные системы] C --> Rust[Rust
Безопасные системы памяти] CPP --> PHP[PHP
Веб-разработка] C --> JavaScript[JavaScript
Веб-скриптинг] Java --> Kotlin[Kotlin
Разработка для Android] style C fill:#ff6b6b style CPP fill:#4ecdc4 style Java fill:#45b7d1 style CSharp fill:#96ceb4

C++ (1985): C с классами (и многим другим)

Бьярн Страуструп взял C и подумал: «Что если мы добавим объектно-ориентированное программирование?» Результатом стал C++, который сохранил мощь C, добавив классы, объекты и наследование.

#include <iostream>
#include <string>
class Programmer {
private:
    std::string name;
    std::string favorite_language;
    int coffee_cups_consumed;
public:
    Programmer(std::string n, std::string lang) 
        : name(n), favorite_language(lang), coffee_cups_consumed(0) {}
    void drink_coffee() {
        coffee_cups_consumed++;
        std::cout << name << " пьёт кофе. Всего: " 
                  << coffee_cups_consumed << " чашек\n";
    }
    void code() {