Язык C — это парадокс. Созданный полвека назад, он до сих пор лежит в основе операционных систем, баз данных и любого «железа», требующего максимальной производительности. Его называют сложным, устаревшим и недружелюбным. Но почему тогда лучшие системные программисты не спешат от него отказываться? Разбираемся в философии, плюсах и минусах C вместе с Максимом Орловым, программистом Postgres Professional с 22-летним стажем.

 

Как я начал учить C и за что его полюбил

Я хотел писать на С ещё со школы. Тогда мы решали задачи на Pascal, и меня бесило, что массивы из 100 и 200 элементов — это разные типы. Я пожаловался другу, он посочувствовал и сказал: «А вот в С по-другому». Так я впервые заинтересовался этим языком, начал его изучать — и мне понравилось.

Другие языки, в частности C++, мне не очень нравятся: объекты загоняют в рамки, начинаются игры в абстракции — кто сможет наиболее абстрактно написать. 

Я люблю приводить пример: всё, что летает, — летающий объект. И самолёт, и утка. А в результате цепочки наследования получается, что у утки шасси не выпускаются. И это ловушка эволюции: мы эволюционно настроены обобщать. Не обобщить труднее, поэтому С сложнее, чем С++, в котором меньше генерализаций.

Системный подход: когда у вас нет права на ошибку

Чтобы понять место C, нужно видеть разницу между системным и прикладным программированием. Если у вас завис браузер (прикладное ПО), вы его просто перезапустите. Но если «упал» сервер СУБД в момент банковской транзакции — это катастрофа.

Системное ПО — консервативный мир, где стабильность важнее новых фич. Языки вроде Python, Perl или JavaScript появились в эпоху, когда процессорное время стало дешевле времени программиста. Стало выгодно решать задачи «экстенсивно», с избыточным расходом ресурсов. C же родом из времён, когда всё было наоборот. Он создан для оптимизации, для выжимания из «железа» максимума. И поэтому он идеален для ядер ОС, драйверов и баз данных.

Почему C жив? Баланс, контроль и немного магии

Почему же технология 50-летней давности до сих пор в строю?

  1. Идеальный баланс. C, как и наш человеческий вид, «средний». Мы не такие сильные, как тигры, и не такие быстрые, как гепарды. При этом, мы социальные и умные. Мы — универсалы. Так и C нашел идеальный баланс между низкоуровневым ассемблером и высокоуровневыми языками.

  2. Ручное управление. В вебе не страшно, если пользователь получит картинку на долю секунды позже. А мы в Postgres Professional иногда выжимаем из процессора такты, чтобы уложиться в нормативы при огромных нагрузках. Такое «ручное управление» железом — уникальная сила C.

  3. Феноменальная переносимость. Модуль, написанный на C, можно скомпилировать практически на любой платформе, и он будет работать. Это фундамент, на котором стоит Unix и всё его наследие.

Стереотип о том, что сишники — это древние люди в свитерах

…не стереотип ☺ Вернее, у него есть свои корни. В дата-центрах тех времён было холодно, чтобы серверы не перегревались. Так что приходилось ходить в свитере. Тогда была важна машина, которая занимала целые залы, а не человек.

C — язык для тех, кому важна суть, а не быстрый результат. Современная разработка часто ориентирована на мгновенный дофамин: написал код, запустил прототип, получил лайк. Язык С — это другая история. Это язык для усидчивых, для тех, кому нравится сидеть и спокойно разбираться в низком уровне, без спешки.

Минусы будут?

Чаще всего С ругают по двум причинам: за указатели и за то, что нет автоматического управления памятью. На мой взгляд, это надуманные проблемы. 

Я заметил, что при изучении программирования с задачками что-то посчитать или меню сделать все справляются. А когда начинаются указатели, становится понятно, кто программист, а кто поиграть пришёл.

Мне в С иногда не хватает шаблонов, приходится решать это другими методами. Ещё нельзя писать функции, которые работают на разных типах данных. Но если реализовать такую функциональность, это будет начало конца: сразу добавится метапрограммирование и другие усложнения. 

Самый обидный баг

Самое обидное для меня в работе — это «железные» ошибки. Их и выявить тяжело, и принять сложно, как это: железо — и не работает? Когда есть подозрение на аппаратную ошибку, я оставляю этот вариант на самый конец, потому что на железо можно списать всё. Сначала нужно проверить весь код, а если проблема не решена — тогда уже можно предположить об ошибке в железе.

С чего начать изучение С

Классическое руководство — «Язык программирования Си» от создателей С Брайана Кернигана и Денниса Ритчи. Там структурированно, подробно и на примерах показано, как работать с С. А дальше нужно просто начать писать: практика — критерий истины. Важно постоянно осмыслять то, что ты делаешь: почему так лучше, а тут не получилось, как сделать эффективнее и пр.

Стоит предусмотреть участие других разработчиков. Им предстоит ревьювить твой код. Без этого не научишься работать. Так, со временем, придёт философское понимание, что такое С.

Программирование — это всегда перевод с человеческого формального языка на язык машин. Поэтому самое важное — понимать идею: если ты понимаешь, что ты хочешь сделать, то всегда напишешь верно. А то, что не выражено словами, закодить нельзя. Этот очевидный факт многие упускают: начинают писать и думают, что «родится по ходу». Это так не работает. 

Как будет развиваться C и будет ли

С — бастион спокойствия. У меня есть книжка «QNX/UNIX: анатомия параллелизма», которой 25 лет, и она до сих пор актуальна. При этом С до сих пор развивается, просто очень медленно. Выходят новые стандарты.

Нужно понимать, что С — язык для системного программирования, где важна стабильность, а не новые фичи. 

А если С надоел и не хочется разбираться во всех его тонкостях, возможно, просто не ваш язык. Так тоже бывает, и это нормально. Вероятно, вам нравится быстро получать результат, тогда это веб-разработка, Python. Если нравится строить абстракции — это C++. А С для тех, кому хочется сидеть и разбираться в низком уровне, спокойно и без спешки.

Когда меня спрашивают, устаю ли я от С, я говорю: «А вы устаете от русского языка?» Язык С — это просто язык: как говорить на русском, английском или на Python. Бывает, что устаешь от задачи, но не от языка. 

Может ли ИИ писать код для системного программирования

Пока ИИ умеет выполнять только самые базовые задачи в программировании, например переложить данные из одного массива в другой по заданному правилу. Но учитывая, что генеративные нейросети до сих пор могут ответить в стиле «у лошади восемь ног», то о сложных задачах говорить не приходится. Успешных кейсов с С, созданных с помощью ИИ, я пока не видел. 

ИИ — просто новый инструмент, как и любой другой. Нужно понять его сильные и слабые стороны и научиться его использовать.


Я уверен, что С еще надолго с нами. Поэтому, если вы хотите на нем писать — вами точно будет чем заняться. Но главное — понять себя. С точно язык не для всех, но если вам нравится скрупулезная тонкая работа, то это может быть начало большой любви, как случилось у меня.

===

В серии рассказов о специалистах, работающих в Postgres Professional, также есть статья о:

performance инженер

Комментарии (4)


  1. Cheater
    10.10.2025 14:29

    TL:DR нейросетевой бред. Или не нейросетевой, но тогда это писал школьник с уровнем знаний "оооо в си есть указатели", а не человек с 20-летним опытом на Си.

    нужно видеть разницу между системным и прикладным программированием. Если у вас завис браузер (прикладное ПО), вы его просто перезапустите. Но если «упал» сервер СУБД в момент банковской транзакции — это катастрофа.

    А вы точно понимаете разницу между системным и прикладным ПО?

    меня бесило, что массивы из 100 и 200 элементов — это разные типы. Я пожаловался другу, он посочувствовал и сказал: "А вот в С по-другому".

    Ну как сказать... Оба типа кастуются в C к обычному указателю в ряде случаев, но эти типы всё равно разные, и слава богу.

    void accept_100(int (*arr)[100]) {}
    
    int main(void) {
        int arr100[100];
        int arr200[200];
    
        accept_100(&arr100); // ok
        accept_100(&arr200); // error: passing argument 1 of ‘accept_100’ from incompatible pointer type
    
        return 0;
    }
    

    получается, что у утки шасси не выпускаются. И это ловушка эволюции

    То есть в правильной иерархии классов утка должна выпускать шасси? Идиотский пример.

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

    Я конечно ИИ-скептик, но мне всё-таки кажется, что на сегодняшний день возможности ИИ в программировании мягко говоря немного больше.


  1. AuToMaton
    10.10.2025 14:29

    Нужно понимать, что С — язык для системного программирования

    Зачем в системном программировании такие штуки как SDL? Разве скриптование Unreal - системное программирование?

    Чаще всего С ругают по двум причинам: за указатели и за то, что нет автоматического управления памятью.

    Скорее за то, что система сборки сложнее самого языка. И за то, что С с Qt не дружит.

    Если нравится строить абстракции — это C++

    С++ помогает строить одни абстракции и мешает строить другие. А С ничему не помогает и ничему не мешает.

    Чего в статье не хватает, так это замечания что как ни FFI, так к С.


  1. saag
    10.10.2025 14:29

    На машинах "которые занимали целые залы" бы ассемблер ЕС, PL/1, Fortran. С был уже на СМ-ках, настольные ЭВМ с портированной операционной системой УНИХ, правда под другим брендом...


  1. Px2
    10.10.2025 14:29

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