Почему некоторые программисты по-разному классифицируют C, Python, C ++? - относительно уровня

16

Я беру вводный курс по питону, и преподаватель говорит, что питон - это язык высокого уровня, а C и C ++ - языки низкого уровня. Это просто сбивает с толку. Я думал, что C, C ++, Python, Java и т. Д. Были языками высокого уровня.

Я читал вопросы в stackoverflow на C, C ++ и т. Д., И все они, похоже, относятся к этим языкам как к высокому уровню. Мне кажется, что некоторые программисты используют эти термины взаимозаменяемо.

atheistlearner
источник
1
Как и многие вещи, высокий и низкий уровень - это упрощение, полезное для понимания, но потенциально вводящее в заблуждение, если вы забудете, что это упрощение. Какой уровень, безусловно, относительный, как говорили другие. Но это не обязательно линия - есть разные направления, в которых вы можете абстрагироваться (например, разные парадигмы). То, что вы отходите от машинной абстракции, не обязательно означает, что вы переходите к подходящей абстракции для вашего приложения.
Steve314
Даже отправная точка может отличаться. Например, в IMO лямбда-исчисление - это очень низкий уровень абстракции - множество абстрагируется в машине, но это очень простая абстракция, которая служит отправной точкой для функциональных языков для начала построения абстракций поверх. В любом случае, лямбда-исчисление, вероятно, не ближе к идеальной абстракции для какого-либо конкретного приложения, чем машинный код.
Steve314

Ответы:

31

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

В настоящее время C считается языком низкого уровня, потому что ни язык, ни стандартные библиотеки не предоставляют никаких структур данных, таких как векторы, словари, итераторы и так далее. Вы можете иметь все эти структуры в программе на C, но в итоге вы сами напишите их. Python, Java и т. Д. Имеют высокий уровень относительно C, потому что многие из этих стандартных структур данных встроены в язык или являются частью стандартных библиотек. Наличие их прямо из коробки облегчает программирование на более абстрактном уровне.

C - низкий уровень во втором смысле: он позволяет напрямую манипулировать аппаратным обеспечением компьютера (по крайней мере, настолько прямым, насколько позволит ОС). Наиболее распространенные реализации Python, Java и т. Д. По крайней мере еще на один шаг удалены от аппаратного обеспечения, поскольку они работают в виртуальной машине. Если вы хотите манипулировать оборудованием из Python, вам нужно написать расширение для Python VM, обычно на C или C ++.

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

Чарльз Э. Грант
источник
3
C ++ на самом деле не такой уж странный случай, IMO - это просто язык смешанного уровня. Уровень получаемой вами абстракции зависит от того, какие функции вы используете.
Steve314
1
@ Steve314: Да и нет: обычно абстракция идет с сокрытием информации, то есть язык или библиотека похожи на черный ящик, который обеспечивает интерфейс, и никто не хочет знать, что находится внутри черного ящика. C ++ немного странный в этом, потому что он предлагает конструкции более высокого уровня, но не мешает программисту получить доступ к их представлению и нарушить их. C ++ - единственный известный мне язык, который не изолирует различные уровни абстракции (но, возможно, есть и другие языки, о которых я не знаю).
Джорджио
1
@Giorgio - C ++ позволяет скрыть любые детали реализации - например, сделать его частью закрытых внутренних объектов класса, поэтому единственный официальный способ его использования - через открытый интерфейс этого класса. Конечно, вы можете нарушать правила и скремблировать вашу память сколько угодно, но на практике вы можете делать это на любом языке, который поддерживает разработку реальных приложений.
Steve314
@ Джорджио - Возьмем, к примеру, Haskell. «Небезопасный» в этом случае имеет тенденцию означать нереферентно-прозрачный (как в unsafePerformIO). Есть IORefтипы, но нет эквивалента, который reinterpret_castя знаю, и нет эквивалента арифметики указателя. Но это не значит, что это безопасно от взлома с памятью. Чтобы быть практичным языком, Haskell должен взаимодействовать с реальными операционными системами и библиотеками. Имеет «интерфейс сторонней функции». Если я действительно хочу подорвать это, все, что мне нужно, это использовать FFI для написания примитивных функций подрывной деятельности.
Steve314
@ Джорджио - Конечно, мне может быть трудно найти значения, которые я хочу испортить в памяти, но то же самое можно применить в C ++, в зависимости от того, насколько хорошо я их спрятал. Например, я мог бы использовать PIMPL . Если я тогда предоставлю только объектный код и заголовок для библиотеки, которая понимает, на что это указывает, то потенциальный подрывной агент должен перепроектировать этот объектный код, чтобы выяснить, что и как подрывать.
Steve314
8

Думайте об этом с точки зрения скользящей шкалы, от языков низкого уровня до языков высокого уровня. Поскольку язык перемещается вверх по шкале, от НИЗКОГО до ВЫСОКОГО, язык обеспечивает все большую абстракцию от конкретного интерфейса с компьютером.

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

Языки высокого уровня пытаются абстрагироваться от мельчайших деталей (в частности, выделения памяти и освобождения памяти). Идея состоит в том, чтобы обеспечить более «естественный» интерфейс для программирования и, надеюсь, позволить программисту сосредоточиться на разработке и производстве.

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

Сравните это с другими языками, такими как Python, Ruby или Haskell, и вы получите гораздо более неясный интерфейс. Эти языки имеют большие библиотеки кода, которые абстрагируют большинство компьютерных команд. Задумывались ли вы, что происходит с переменной в Python, когда вы покидаете локальную область функции или удаляете ее? Наверное, не правильно? И это потому, что на языке высокого уровня вам не нужно! Они присматривают за выделением / освобождением памяти для вас.

Языки высокого уровня имеют преимущество функции. Они позволяют нам свободно проектировать и разрабатывать (и безопасно!).

Языки низкого уровня имеют преимущество в скорости в большинстве случаев. Существует интерпретация кода высокого уровня. Плюс, это здорово написать что-то в «компьютерном разговоре».

Надеюсь это поможет

Ник Бернс
источник
5

Высокий уровень против низкого уровня - это не черно-белая вещь, а непрерывная шкала. Термины используются для описания того, насколько близко язык программирования к аппаратному обеспечению; чем выше уровень, тем больше он отвлекает оборудование.

Самым низким уровнем, очевидно, является двоичный машинный код - это точное представление загрузки ОС и ее загрузки в ЦП. Сборка - это первый уровень абстракции, построенный на ее основе: вместо двоичного кода пишут мнемосхемы, читаемые человеком символические коды, которые представляют двоичные машинные инструкции. Это то, что люди использовали для системного программирования до UNIX.

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

C ++ добавляет еще один уровень абстракций: он добавляет классы (абстрагирование vtables и контекста, передаваемых в синтаксис OOP), newи delete(объединение выделения памяти и инициализации переменных в одну конструкцию), проверка типов во время компиляции, шаблоны (безопасные во время компиляции) метапрограммирование), а также набор синтаксических удобных функций во время компиляции, таких как пространства имен, перегрузка функций и операторов и т. д.

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

Поэтому, когда люди делят языки на языки «высокого уровня» и «низкого уровня», они где-то проводят произвольную линию, и эта линия не всегда одинакова. В 1970 году была проведена грань между сборкой и C (решающим фактором было абстрагирование машинных инструкций для конкретной платформы); в 1987 году он мог находиться где-то между C и C ++; сегодня это может быть между C ++ и Java (решающим фактором является автоматическое управление памятью).

Короче говоря: высокоуровневый уровень - это скользящая шкала, и для трех упомянутых вами языков это C <C ++ <Python.

tdammers
источник
Я бы сказал, что высокий уровень против низкого уровня - это не одна шкала, а две отдельные шкалы. Низкоуровневость связана с тем, насколько хорошо язык относится к поведению машины, а высокоуровневость связана с его способностью предоставлять абстракцию. C # является более высокоуровневым языком, чем C99, но также является более низкоуровневым, чем язык, определенный в Стандарте C, поскольку поведение, например, заключается в использовании указателя «int» для обработки «коротких» значений в массиве два при время определяется в C #, но не в C99.
Суперкат
3

Граница между языками «низкого уровня» и «высокого уровня» время от времени меняется.
Например: еще
во времена UNIX C был языком высокого уровня.
Сегодня C не имеет таких структур, как типы отображения (словари), итераторы и т. Д., Которые есть в современных языках высокого уровня, таких как Python. Таким образом, линия изменилась, и C теперь попал в группу низкого уровня.

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

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

pradyunsg
источник