it-roy-ru.com

Что делает C таким популярным в эпоху ООП?

Я много пишу на C и C++, но не ожидал, что C будет вторым по популярности языком, немного уступая Java.

Индекс сообщества программистов TIOBE

Мне любопытно, почему в этом веке ООП C все еще так популярен? Обратите внимание, что 4 из 5 популярных языков программирования являются "современными" объектно-ориентированными языками.

Теперь я согласен, что вы можете использовать OOP в C в некоторой степени, но это довольно болезненно и неэлегично (по крайней мере, по сравнению с C++, я думаю). Итак, что делает C таким популярным? Это эффективность, низкий уровень, подавляющее большинство библиотек, которые уже существуют, или что-то еще?

92
GradGuy

Несколько факторов, которые способствуют:

  • С вездесущ. Независимо от платформы, C, вероятно, доступен.
  • С является портативным. Напишите кусок чистого C, и он компилируется с минимальными изменениями на других платформах - иногда он даже работает "из коробки".
  • С был вокруг некоторое время. В те времена, когда UNIX завоевывал мир, C (предпочитаемый язык программирования UNIX) разделял свое мировое господство и стал lingua franca мира программирования. Можно ожидать, что любой серьезный программист, по крайней мере, поймет немного смысл фрагмента C; то же самое нельзя сказать о большинстве других языков.
  • C по-прежнему является языком по умолчанию для систем UNIX и UNIX. Если вы хотите, чтобы библиотека преуспевала на земле с открытым исходным кодом, вам нужны довольно веские причины не для использования C. Это частично связано с традицией, но больше потому, что C - единственный язык, на который вы можете смело предположить поддерживаться в любой UNIX-подобной системе. Написание вашей библиотеки на C означает, что вы можете минимизировать зависимости.
  • С прост. Ему не хватает выразительности сложных OOP или функциональных языков), но его простота означает, что его можно быстро подобрать.
  • С универсален. Он подходит для встраиваемых систем, драйверов устройств, ядер ОС, небольших утилит командной строки, больших настольных приложений, СУБД, реализации других языков программирования и практически всего, о чем вы только можете подумать.
  • С быстро. Большинство реализаций C компилируются непосредственно в машинный код, и программист имеет полную власть над тем, что происходит на машинном уровне. Здесь нет ни интерпретатора, ни JIT-компилятора, ни VM, ни времени выполнения - только код, компилятор, компоновщик и голый металл.
  • C является "свободным" (как в пивном, так и в речевом смысле). Нет ни одной компании, которая владеет и контролирует стандарт, есть несколько реализаций на выбор, нет проблем с авторским правом, патентами или товарными знаками при использовании C, и некоторые из лучших реализаций являются открытыми.
  • C имеет большой импульс. Язык был популярен в течение десятилетий, поэтому существует огромное количество приложений, библиотек, инструментов и, прежде всего, сообществ для поддержки языка.
  • С зрелый. Последний стандарт, который внес большие изменения - это C99, и он в основном обратно совместим с предыдущими стандартами. В отличие от более новых языков (скажем, Python), вам не нужно беспокоиться о том, что в ближайшее время могут произойти изменения.
  • С совместим. У большинства языков есть привязки для общения с C. Это означает, что можно разработать библиотеку на C, используя стандартные соглашения о вызовах, и быть уверенным, что почти любой другой язык может ссылаться на эту библиотеку. Чтобы назвать несколько популярных языков для широкого использования: C #, Java, Perl, Python, PHP может без проблем связываться с библиотеками C).
  • C мощный: если язык не может что-то сделать, все популярные компиляторы позволяют встраивать ассемблерный код, который может делать все, что может аппаратное обеспечение. В сочетании с вышеуказанным пунктом о совместимости это означает, что C может служить связующим звеном между языками более высокого уровня и "голым металлом" сборки.
142
tdammers

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

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

И этот последний момент стоит немного побить. Читайте дальше, если вы заинтересованы в изучении на физическом уровне того, почему существуют определенные стили программирования, как они работают вместе и куда движется мир в будущем, когда мы продолжим изучать такие концепции ...

Объект в физике - это все, что поддерживает узнаваемую согласованность во времени. Это, в свою очередь, позволяет таким простым существам, как мы, с легкостью представлять объект, используя лишь небольшое количество битов, не подвергая опасности свое выживание. Но с точки зрения физики в целом, число вещей, которые вы должны сделать совершенно правильно, чтобы сделать такое упрощение простым и распространенным, удивительно велико. Как люди, мы не думаем обо всем этом, потому что, честно говоря, нас бы здесь не было, если бы это было не так.

Звучит слишком абстрактно? Это действительно не так. Представьте себе, например, попытку пройти по дороге к дому вашего друга, если вместо автомобилей вы столкнулись с быстро колеблющимися плазменными полями и мгновенными конденсациями вещества, движущимися с огромным диапазоном скоростей. Такой сценарий может довольно сильно сократить возможности социализации, да? Нам нужны объекты, мы являемся объектами, и существование объектов предоставляет нам огромный и критически важный уровень упрощения окружающей нас среды.

Итак, давайте вернемся к программному обеспечению. Что объекты в реальном мире говорят об объектах с точки зрения программирования?

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

С определением, самые простые формы OOP легко распознаются. Это те, которые немного справляются, используя только те данные, которые уже "прикреплены" или определены каким-то реальным миром, действительно физический объект, такой как человек, дом или автомобиль. Даже сегодня это все еще слишком часто только определение объектов, которые люди получают на курсах программного обеспечения. Это очень плохо, потому что даже тривиальные объектно-ориентированные программы нужно более широкое определение, чем это.

Вторая и гораздо более интересная категория объектов состоит из того, что я назову увековеченные события реального мира. Под "увековеченным" я подразумеваю вещи, которые по крайней мере кратко существуют как четко определенная сущность или коллекции в реальном мире, но которые затем рассеиваются и перестают существовать как физически значимые коллекции. Симпозиум является отличным примером: симпозиум существует в течение короткого времени как прилично четко определенный набор мест и людей. Но, увы, даже лучшие конференции должны заканчиваться, и отдельные составляющие их части переходят к другим видам деятельности.

Но используя компьютеры и сети, мы можем сделать такой переходный симпозиум кажется долгосрочным объектом, захватив и сохранив в памяти его как программный объект. Очень многое из того, что мы делаем с компьютерами и базами данных, сводится к такого рода иммортализации переходных событий, когда мы фактически пытаемся сделать нашу настоящую вселенную более богатой, захватывая и расширяя ее таким образом, что физически не может существовать. Например, ты видел настоящего Пандору в последнее время? Такие захваты и расширения реальных произведений помогают удивительным образом обогатить и расширить нашу собственную жизнь, экономику и выбор. Для меня это является сердцем объектно-ориентированного программирования, местом, где оно оказало и продолжает оказывать наиболее значимые воздействия.

Последняя категория OOP состоит из объектов, которые не имеют тесной связи с внешними событиями, но вместо этого инфраструктура необходимы для поддержки нашего продолжающегося расширения реальности с использованием увековеченных объектов из реальный мир. Здесь вы можете спуститься вплоть до (полу) металла компьютера, создавая части постоянной реальности, которые подобно химическим элементам реального мира можно быстро и интересным образом комбинировать для создания нового внутреннего миры. Мобильные вычисления помогли продвинуть развитие такого высоко рекомбинаторного подхода, который во многих отношениях повторяет рекомбинаторные особенности физического мира. Это также трудно: то, что со временем может показаться хорошим выбором, может иметь был неожиданно плохим, обычно потому, что он блокирует разнообразие и расширение, а не поддерживает его.

Эта последняя категория также указывает на риск использования только одной модели для программирования, поскольку, как и в реальном мире, программируемым мирам также нужны процессы, которые не хорошо соответствуют относительно неизменным объектам. Земля полна объектов, но Солнце наполнено высокодинамичными потоками энергии, которые в конечном итоге необходимы для "управления" объектами и деятельностью на Земле с более низкой энергией. Точно так же при создании вычислительных миров существуют случаи, когда вам приходится иметь дело с потоками и преобразованиями, а также с быстро меняющимися контекстами, которые, хотя и не очень объектно-подобны сами по себе, тем не менее абсолютно важны для включения более простых, более дружественных для человека объектов, используемых на более высоких уровнях. , Не случайно, что большая часть программирования, выполняемого на уровне ядра, не является явно объектно-подобной или что она в значительной степени опирается на языки типа C, которые более ориентированы на обработку. Это более глубокие области, которые дополняют увлекательное разнообразие, которое мы видим выше в мире, созданном компьютером. Попытка втиснуть их в чистые объектные модели может напоминать Солнцу, что его нужно реорганизовать в несколько миллиардов аккуратных каминных объектов, чтобы мы могли легче понимать и ориентироваться с точки зрения человека.

Другая область, в которой OOP может пойти не так, как надо) слишком сильно фокусируется на старых концепциях объектов.

Объекты в реальном мире, и особенно живые объекты, обладают абсолютно удивительным уровнем способности взаимодействовать со своей средой сложными и тонкими способами. Композиционные виджеты, которые просматривают друг друга, выполняют некоторые проверки совместимости и работоспособности и, возможно, даже находят новые способы взаимодействия, намного ближе к реальной биологической концепции объектов, чем простые структуры и простые схемы наследования, к которым мы стремимся. сосредоточиться на (обычно по необходимости!) на уровне кода. Это одна из областей роста объектов в кибер-мире, более "агентоподобные" подходы, где реактивность к среде является нормой даже внутри самого программирования.

И так много для моей "критики" ООП! Тем не менее, я надеюсь, что я указал, почему создание более богатого кибермира означает охватывающий разнообразие стилей программирования, а не предполагает, что "только один" - это все, что необходимо. Я чувствую, что действительно интересные вещи еще впереди, независимо от того, насколько обыденным является то, что мы делаем сейчас!

88
Terry Bollinger

Во-первых, вам не нужно OOP для всего, несмотря на то, что догмы об этом были популяризированы. В отличие от Java, C допускает указатели на функции и даже замыкания , что открывает дверь к функциональному программированию и решает довольно большую часть проблемного пространства OOP, потому что он предоставляет средства для внедрения зависимостей. Также осторожен использование макросов может на самом деле создавать очень хорошие вещи, как sglib доказывает.

Странным образом можно увидеть C как хороший компромисс между Java и C++. Обратите внимание, что я нет говоря, что C - это в любом случае и то, и другое, но в отличие от Java это довольно мощный язык, в то время как в отличие от C++ он имеет управляемую сложность.

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

25
back2dos

C имеет ABI (двоичный интерфейс приложения), а C++ - нет. Это делает C более полезным, чем C++, в некоторых случаях. Если я собираюсь написать библиотеку и иметь возможность поставлять двоичные файлы для использования другими людьми, C++ - неподходящий инструмент для работы. Если я собираюсь написать библиотеки, которые будут использоваться другим языком снова, C - правильный инструмент для работы. Я никогда не слышал о языке, который не поддерживает FFI (интерфейс внешних функций) для C, с другой стороны, C++ не будет работать с библиотеками, написанными на C++, если используются разные компиляторы.

По сути, это сводится к тому, что C выполняет роль, для которой C++ не подходит.

21
stonemetal

Одно из преимуществ использования C над такими языками, как C++ или Java) заключается в том, что под капотом не происходит много магии. Конструкторы не запускаются, когда элементы выделяются, и деструкторы не запускаются. когда объекты выходят из области видимости. Там нет искажения имен и нет vtables. Производительность легче предсказать, вам не нужно беспокоиться о том, что сборщик мусора прервет процедуру и откажется от ее времени.

Конструкторы, деструкторы, искажение имен, vtables, сборщики мусора и т.д. Могут облегчить некоторые сложности в написанном вами коде, но затем эта сложность становится частью самого языка, где вы почти не можете контролировать это. Вы можете получить более длительное время сборки (раздражающее, но допустимое), больший объем памяти во время выполнения (может или не может быть приемлемым) или более низкую производительность. С C вы можете избавиться от некоторых из этих сложностей, пока не останетесь с функциональностью, которую вы нужно.

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

12
John Bode

Встроенные системы и драйверы обычно программируются на C. Помимо этого, существует множество устаревших систем C, которые все еще поддерживаются и расширяются.

11
EricSchaefer

То же самое, что делает ручной молот популярным в эпоху пневматических молотков (пневматических молотков): C по-прежнему подходит для определенных задач.

10
anon

Простота, последовательность и точность.

Это просто - вам не нужна сложная среда разработки, обширные библиотеки или виртуальная машина.

Это согласуется - большинство C, написанных 10 лет назад, могут компилироваться сегодня.

Точность - это позволяет вам опуститься до уровня машины, зная места памяти по мере необходимости. Это отлично подходит для производительности и встроенного оборудования.

Это не для всех, но это все еще полезный инструмент.

6
MathAttack

Я привожу два момента из другого ответа, потому что они точно отражают причины, по которым я все еще время от времени пользуюсь Си (хотя это не мой основной язык выбора):

  • C прост. Ему не хватает выразительности сложных OOP или функциональных языков, но его простота означает, что его можно быстро подобрать.
  • C зрелый. Последним стандартом, внесшим большие изменения, является C99, и он в основном обратно совместим с предыдущими стандартами. В отличие от более новых языков (скажем, Python), вам не нужно беспокоиться о том, чтобы в ближайшее время прервать изменения.

Я думаю, что это очень верно. Я выучил C в начале ночных сороковых: это было просто, мало ключевых слов и конструкций, большая часть работы выполнялась библиотеками. Тогда я не использовал C в течение нескольких лет. Примерно в 2002 году мне понадобилась быстрая реализация алгоритма, я установил компилятор C и реализовал его. Я знаю язык, знаю, для чего он хорош, для чего он не годится (я бы никогда реализовывал веб-приложение на C!), И это как раз там, когда мне это нужно. Без сюрпризов.

С C++ у меня был другой опыт. Я узнал об этом примерно в 1995 году, и это означало большой переход парадигмы с императива на ООП. Большой! Я использовал его для нескольких проектов до 1999 года. В течение нескольких лет я не использовал C++, и когда я снова поднял его (2008), я обнаружил множество новых функций уже в языке, и даже более запланированных (в то же время введенных в C++). 11). У меня возникло ощущение, что я должен снова выучить язык.

Как разработчик, я предпочитаю зрелые, стабильные языки. Мне нравится изучать язык один раз, понять его принципы дизайна, для чего он нужен, и использовать его, когда я считаю, что это правильный инструмент для работы. Мне также нравится изучать разные языки и выбирать язык, который мне подходит (C, C++, Java, Scala, Haskell и т.д.). Что мне не нравится, так это снова и снова изучать один и тот же язык, потому что он развивается все дальше и дальше и никогда не достигает зрелости.

ИМХО, язык программирования должен иметь четкий, слаженный и стабильный дизайн. Мне нравится подход таких дизайнеров, как Никлаус Вирт: каждый раз, когда он чувствовал потребность в другом языке, он проектировал новый (Паскаль, Модула-2, Модула-3, Оберон). Мне не нравятся языки, которые подвергаются важным изменениям каждые 5-10 лет: они похожи на движущиеся цели, и я никогда не чувствую, что стоит потратить время на их глубокое изучение, потому что версия, которую я изучаю сейчас, вероятно, устареет через несколько лет в любом случае.

В этом смысле C является IMO победителем: это хорошо для определенных приложений и менее подходит для других, но имеет то преимущество, что оно простое и относительно стабильное.

6
Giorgio

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

4
Dan Martinez

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

  • Язык C намного проще, чем C++. Я не знаю ни одной компании, которая использует полный стандарт C++ в своем соглашении о кодировании. Взгляните на стиль кода Google C++ в качестве примера: http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml
  • С гораздо быстрее компилируется. Благодаря отсутствию сложных для компиляции конструкций.
1
Konstantin Solomatov

Ничего. TIOBE - бесполезный показатель. Если вы действительно посмотрите на их измерения, это абсолютное предположение - в лучшем случае.

0
DeadMG

много устаревшего программного обеспечения

Многие компании не могут изменить сразу весь свой код на C++ или аналогичный.

Многие компании не могут позволить себе изменить свой код.

Многие компании могут позволить себе изменить свой код, но им все равно, или они "дешевы".

Многие компании находятся в процессе миграции, но еще не закончили.

Ориентация на поиск предметов

(Не объектно-ориентированный) Исходный код C, разработанный как объектно-ориентированный исходный код C, приложения, которые смоделированы с помощью Object Orientation и закодированы с использованием "чистого C", или инструменты, которые переводятся из "C++" или других O.O. прогр. Ланг в C.

Я слышал, что некоторые видеоигры сделаны таким образом. Некоторые кроссплатформенные инструменты, а также библиотека визуального интерфейса GTK (GObject, GLibrary) для GNome Linux O.S. Распределения.

0
umlcat

Потому что C имеет огромную базу пользователей. Да, это немного ловушка, но когда я задаю вопрос о C в StackOverflow, я получаю ответ почти мгновенно. Тот же вопрос о Python может занять несколько часов, чтобы получить ответ.

Что касается C++, IMO сложнее в освоении. Кроме того, после попытки OOP в течение 10 лет, я обнаружил, что это не всегда полезно, и часто вместо этого проще использовать процедурное программирование.

0
puk

Я вижу, что некоторые из респондентов рассказывают, почему C является самым популярным, он существует уже давно, доступен на большинстве платформ, бесплатен и т.д.

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

Паскаль был изобретен около 1970 года, С был изобретен около 1972 года, поэтому я думаю, что Паскаль существует примерно столько же, сколько С.

Лично я думаю, что C - самый популярный язык, потому что есть только больше открытого исходного кода, доступного для повторного использования любым. И да, это более низкий уровень, чем у Pascal, поэтому он приближается к Assembly, но гораздо более читабелен, чем Assembly.

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

Кажется, C - это тот глобальный язык, но я бы хотел, чтобы это было что-то вроде Object Pascal. Почему Object Pascal, это более читаемый язык программирования, OOP код, как правило, более пригоден для повторного использования и менее подвержен ошибкам (на мой взгляд), чем C.

Очень большими приложениями легче управлять с помощью Object Pascal, чем C/C++.

Что касается языка программирования, существовавшего с 70-х годов, и не любящих языков, которые меняются каждые 5 или 10 лет. Со временем технологические достижения и методы программирования совершенствуются. Если язык резко меняется каждые несколько лет, то, вероятно, его разработчик не очень хорошо продумал. Но с 1970 по 2012 год - это почти полвека, поэтому можно вносить изменения в язык в то время, чтобы включать в себя достижения, используемые в разработке программного обеспечения.

Сам C был пересмотрен несколько раз. Так что это не лучше, чем другие языки формируют эту точку зрения.

0
Sergio Fernandez