Язык 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 инженер

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


  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. Serpentine
      10.10.2025 14:29

      нейросетевой бред.

      С большой долей вероятности нейронка не причислила бы Кернигана к «создателям» Си:

      «Язык программирования Си» от создателей С Брайана Кернигана и Денниса Ритчи.


  1. AuToMaton
    10.10.2025 14:29

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

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

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

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

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

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

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


  1. saag
    10.10.2025 14:29

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


    1. APh
      10.10.2025 14:29

      Точно! Ибо серия СМ ЭВМ (те, которые в архитектуре DEC PDP) — родной дом Си.


    1. plus79501445397
      10.10.2025 14:29

      На мейнфремах EC была Мобильная операционная система (МОС ЕС) - портированный unix с Си конечно же. Кроме того на EC был и компилятор Си вне какого либо unix. Знака фигурных скобок не было на стандартной клавиатуре терминалов EC-7920, поэтому вместо него набирали сочетание из двух знаков.


  1. Px2
    10.10.2025 14:29

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


    1. AbitLogic
      10.10.2025 14:29

      Забей там инженер-программист, работы полно, толковых мало


      1. Px2
        10.10.2025 14:29

        Забил. Нет там ничего для сишников. В основном С++.


    1. jingobo
      10.10.2025 14:29

      В Embedded широко распространен Си и толковых разработчиков там днем с огнём не ссышешь.


      1. AlexanderS
        10.10.2025 14:29

        Там же проблема больше не в знании Си как таковом, а в инженерно-техническом понимании этого самого Embedded.


        1. blind_oracle
          10.10.2025 14:29

          Проблема там в оплате. Эмбедщикам никто не хочет платить и самые толковые ушли в другие сферы.


          1. AlexanderS
            10.10.2025 14:29

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


            1. blind_oracle
              10.10.2025 14:29

              Не, я не про сейчас, а вообще.

              Формошлёп всегда получал в среднем больше эмбедщика, к сожалению, по крайней мере в РФ. Хотя скиллы не сопоставимы.

              На западе немного более выровнено, если не считать фаанги.

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


  1. Pusk1
    10.10.2025 14:29

    Вот для меня в глубине души C++ так и остался объектным расширением С. Интересно, сейчас код на С можно скомпилировать С++ компилятором?


    1. ImagineTables
      10.10.2025 14:29

      Вот для меня в глубине души C++ так и остался объектным расширением С.

      Как и для большинства программистов, которых я знаю.


    1. Panzerschrek
      10.10.2025 14:29

      Технически компилятор C и компилятор C++ это одна и та же программа, которая просто запущенна с разными опциями. Но скомпилировать C код в режиме C++ скорее всего не получится, ибо C++ не позволяет некоторых вольностей C, вроде молчаливого неявного преобразования указателей.


    1. Melirius
      10.10.2025 14:29

      Зависит от вашего стиля кода. Я приловчился, так пишу, что в 99% можно. Но и мой C++ в результате очень олдскул :)


  1. omxela
    10.10.2025 14:29

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


  1. Emelian
    10.10.2025 14:29

    C++, мне не очень нравятся

    А мне, наоборот, С++ нравится больше, чем Си. На Си любят писать консольные программы, а на С++ – оконные. Соответственно статьи по Си – редко содержат картинки программ, разве, что просто изображения себя любимого.

    Хотя, оконные программы на Си тоже есть. Например, консольный видеопроигрыватель FFPlay.c. Но, вот, прилепить его к своей оконной программе – с разбегу не получится. На Гитхабе, я так и нашел, хорошего прототипа. Поэтому, поступил проще. Преобразовал Си-код проигрывателя в классы С++ и подключил, без особых проблем, к своей оконной программе «МедиаТекст» на С++ / WTL (см. скриншот: http://scholium.webservis.ru/Pics/MediaText.png ).

    Так что, как говориться: «На вкус и цвет – товарищей нет!».


  1. AlexeySu
    10.10.2025 14:29

    Самый страшный страх сишника:

    Мне не хватает шаблонов.... (но)

    ...это будет начало конца: сразу добавится метапрограммирование и другие усложнения.

    Боязнь острого ножа, а то вдруг порежусь


    1. Melirius
      10.10.2025 14:29

      Кстати, дженерики-то уже и в С завезли..


      1. codecity
        10.10.2025 14:29

        А подробнее?


        1. Melirius
          10.10.2025 14:29

          https://en.cppreference.com/w/c/language/generic.html

          Оно, конечно, такое же кривое, как и modern C++, но есть.


          1. codecity
            10.10.2025 14:29

            В C++ все же красивше. В C бывают злоупотребляют макросами, так что сразу хрен поймешь что имелось в виду.


    1. segment
      10.10.2025 14:29

      Ну "боязнь" вполне оправдана - посмотрите что сейчас творится с C++ и его метапрограммированием. Я писал на плюсах довольно долго, и мне очень нравились лекции Констатина Владимирова, где понятны концепции которые преследуют разработчики. Но в реальных проектах все эти замысловатости могут добавлять скрытых проблем и приводит к удорожанию стоимости поддержания кодовой базы. В моей практике "явное лучше неявного" при написании кода.


  1. codecity
    10.10.2025 14:29

    В C есть макросы, бывают трехэтажные и более. Еще хуже шаблонов.


  1. d3d11
    10.10.2025 14:29

    Я пишу на чистом С, и у меня есть соответствующий свитер ))


  1. pulichkin
    10.10.2025 14:29

    сидеть и разбираться в низком уровне, спокойно и без спешки.

    Интересно где такая работа есть(чтоб спокойно и без спешки) ?) И чтоб за это ещё и хорошо платили