Как узнать, на каком языке программирования написана программа

Обновлено: 21.11.2024

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

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

Обычно программист пишет инструкции на выбранном языке более высокого уровня, в нашем случае на Java, и эти инструкции или исходный код хранятся в текстовом виде в файле. Затем этот исходный файл передается программе, называемой компилятором, которая переводит исходный язык в объектный код в двоичной форме и записывает его в другой файл, называемый программой. Примером может служить файл .exe в Windows. Может быть дополнительный шаг, называемый связыванием, который представляет собой процесс объединения инструкций программиста с библиотеками инструкций, созданными кем-то другим. Иногда файл программы может быть отправлен на другой компьютер для выполнения. Это называется развертыванием.

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

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

Помню, 5 лет назад я обнаружил вызов API, который требует дескриптор окна и возвращает имя класса окна. Я заметил, что если программа написана на VB, перед именем класса любого объекта должно стоять слово «гром». Если он написан в Delphi, имя класса обычно обозначается буквой «T». Я не уверен, что это все еще так.

14 ответов 14

Конечно, если они использовали упаковщик, сначала нужно будет выполнить некоторую распаковку :)

PEiD v0.95 (2008.11.03) успешно загружен из указанной выше папки и работает под управлением Windows 7 Pro 64. Однако PEiD сообщает, что это недопустимый PE-файл для большинства, но не для всех файлов .exe и .dll в моей системе. . Я предполагаю, что PEiD работает для старых двоичных файлов, но не актуален для новых.

Запустите его и проверьте, какие библиотеки DLL времени выполнения он использует с помощью Process Explorer.

Если сразу это не становится очевидным, поищите в Интернете ссылки на эти библиотеки DLL.

Большинство дизассемблеров (включая Olly, я думаю) могут легко показать вам текст, содержащийся в EXE или DLL, и это также иногда может дать подсказку. Типы Delphi часто имеют префикс T, как в TMyClass.

Если это небольшой исполняемый файл без ссылок на DLL и без текста, вы можете быть SOL. В этот момент вам нужно будет искать идиомы конкретных компиляторов, и это будет в основном догадка.

Определить, на каком языке написана программа, — это искусство. Это возможно, но жестких правил не существует. Это требует большого опыта (и также приводит к вопросу "Зачем вам это нужно?", но вот несколько идей о том, как это сделать.

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

Кроме того, существуют стили развертывания приложения: различные файлы конфигурации, находящиеся в каталоге развертывания, библиотеки DLL и сборки и даже изображения, каталоги или значки.

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

Многие компиляторы собирают и связывают код определенным образом и оставляют следы. Например, изучая исполняемый файл окна с помощью вкладки «strings:» в Process Explorer, вы увидите множество строк. Используя их, вы сможете определить стили программирования, вызываемые методы, методы ошибок или трассировки внутри исполняемого файла.

Например, компиляторы используют разные механизмы для локализации: Microsoft хранит локализованные строки в XML-файлах или файлах ресурсов. Другие компиляторы будут использовать другую тактику.

Еще один пример — изменение имени в C++. Компилятор CodeWarrior использует другой алгоритм для изменения имен переменных-членов и функций вызова, чем Visual Studio.

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

Надеюсь, я правильно сформулировал вопрос. Мне просто любопытно, есть ли способ определить, какой язык программирования использовался для конкретного приложения .exe. Я новичок в программировании, начинаю изучать VB, и, как и многие другие, мне интересно, лучший ли это язык для изучения. Я думал, что если бы я мог определить, какой язык(и) программирования использовался при создании некоторых из моих любимых исполняемых файлов, тогда я мог бы оценить возможности каждого из них и решить, какой из них подходит мне. Кроме того, как и в веб-дизайне, где иногда бывает полезно просмотреть исходный код страницы, чтобы определить, как достигаются определенные эффекты, я думаю, было бы полезно изучить исходный код других программ. Я пробовал очевидное — просто открывал .exe с помощью текстовой программы, но все, что я вижу, — это мешанина символов. Эта кодировка предназначена для того, чтобы скрыть программирование?

  • 5 участников
  • 7 ответов
  • 3 000 просмотров
  • Продолжительность обсуждения – 1 месяц.
  • Последнее сообщение 14 лет назад Последнее сообщение от Нару

Рекомендуемые ответы

> Я новичок в программировании, начинаю изучать VB, и, как и многие другие, мне интересно, является ли
> лучшим языком для изучения.
Абсолютно нет. Есть языки получше, такие как Java, Python и т. д.

> тогда я мог бы оценить возможности каждого из них и решить, какой из них…

Боюсь, эти люди ошибаются в одном отношении.
В большинстве случаев есть способ определить язык программирования (или, по крайней мере, компилятор) на основе подписи исполняемого файла. У каждого компилятора, упаковщика и средства модификации исполняемого файла есть уникальный «отпечаток пальца», который он оставляет на файле. Большинство…

Все 7 ответов

> Я новичок в программировании, начинаю изучать VB и, как и многие другие, задаюсь вопросом, является ли
> лучшим языком для изучения.
Абсолютно нет. Есть языки получше, такие как Java, Python и т. д.

> тогда я мог бы судить о возможностях каждого и решить, какой из них подходит мне
Вы не судите о достоинствах языка программирования на основе того, генерирует ли он и исполняемый файл или нет!!

> Думаю, было бы познавательно изучить исходный код других программ.
Что касается обучения на чужом коде, зайдите на sourceforge, который является домом для многочисленных проектов с открытым исходным кодом, просто выберите свой любимый проект на языке программирования и начните изучать/вносить свой вклад.

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

>Как определить язык программирования файла .exe?
Вы можете разобрать исполняемый файл и воссоздать дизайн программы. Из этого иногда можно вывести исходный язык, на котором она была написана. Однако это требует большого опыта и таланта в обратном проектировании, а также близкого знакомства с языком ассемблера и любым из возможных языков, на которых могла быть написана программа. написано в.

Короткий ответ: вы не можете.

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

>Как определить язык программирования файла .exe?
Вы можете разобрать исполняемый файл и воссоздать структуру программы. Из этого иногда можно вывести исходный язык, на котором она была написана. Однако это требует большого опыта и таланта в обратном проектировании, а также близкого знакомства с языком ассемблера и любым из возможных языков, на которых могла быть написана программа. написано в.

Это не так сложно. Сначала вы можете просто найти имя компилятора. Для Haskell вы можете использовать grep '.lhs'. Если это не удается, то для любого скомпилированного языка gc вы можете просто посмотреть на сборщик мусора. Это, эм, сложнее. Но перед этим: если вы видите строки формата printf, это, вероятно, на C или C++.Например, вы можете узнать, что Firefox использует некоторое количество C++, просматривая его исполняемый файл и ища строку «::», пока не встретите несколько строк сообщений об ошибках, и отметив, что он также имеет несколько строк формата.

Строки сообщений об ошибках — ваши лучшие друзья.

Спасибо всем за участие и пояснения. -ФастФред

Боюсь, эти люди ошибаются в одном отношении.
В большинстве случаев есть способ определить язык программирования (или, по крайней мере, компилятор) на основе подписи исполняемого файла. У каждого компилятора, упаковщика и средства модификации исполняемого файла есть уникальный «отпечаток пальца», который он оставляет на файле. Большинство этих инструментов можно найти в довольно темной «подпольной» среде, где тусуются реверсеры и взломщики (поскольку необходимо знать, какой тип упаковки произошел в файле, прежде чем вы попытаетесь реконструировать его). Один из таких инструментов, который я регулярно использую, называется PEid. Вы можете найти его в Google, но обязательно выполните тщательное сканирование на вирусы (' data-bs-template='

Спасибо, друг. Я поищу и попробую PEid. С тех пор, как я начал эту тему, я начал изучать VB. Я знаю, что многие люди могут сказать, что это не лучший выбор языков программирования, но я думаю, что было бы почти невозможно получить 100% консенсус в отношении того, ЧТО ТАКОЕ лучший язык программирования. Конечно, есть люди, которые разбираются во всех языках и, следовательно, имеют право судить о каждом из них по достоинству, но я уверен, что многие программисты просто неравнодушны к тому языку, с которым они лучше всего знакомы. По крайней мере, это справедливо при обсуждении брендов компьютеров, автомобилей, спортивных команд и т. д. Так почему же выбор лучшего языка программирования должен быть другим? Несмотря на это, для того, чтобы я мог принять собственное решение о том, какой язык лучше для меня, я должен с чего-то начать. Так что я начал с VB, и я довольно хорошо продвигаюсь. Еще раз спасибо всем, кто высказался по этой теме.

Я знаю, что многие люди могут сказать, что это не лучший выбор языков программирования, но я думаю, что почти невозможно получить 100% консенсус в отношении того, ЧТО ТАКОЕ лучший язык программирования. Конечно, есть люди, которые разбираются во всех языках и, следовательно, имеют право судить о каждом из них по достоинству, но я уверен, что многие программисты просто неравнодушны к тому языку, с которым они лучше всего знакомы. По крайней мере, это справедливо при обсуждении брендов компьютеров, автомобилей, спортивных команд и т. д. Так почему же выбор лучшего языка программирования должен быть другим? Несмотря на это, для того, чтобы я мог принять собственное решение о том, какой язык лучше для меня, я должен с чего-то начать. Итак, я начал с VB и неплохо продвигаюсь.

Хе-хе, похоже, вы пытаетесь оправдать свое решение перед самим собой. ;)

Вы правы, конечно. В VB нет ничего плохого, и если вы попытаетесь найти лучший язык для начала, вы никогда ничего не добьетесь. Общий объективный совет — просто выбрать язык и начать изучение. По мере того, как вы будете узнавать больше, вы найдете новые направления для движения, и хорошие программисты усвоят одни и те же уроки, независимо от того, с чего они начинали.

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

Наши редакторы рассмотрят то, что вы отправили, и решат, нужно ли пересматривать статью.

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

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

Компьютеры размещают веб-сайты, состоящие из HTML, и отправляют текстовые сообщения так же просто, как. РЖУ НЕ МОГУ. Взломайте этот тест, и пусть какая-нибудь технология подсчитает ваш результат и раскроет вам его содержание.

Типы языков

Машинные и ассемблерные языки

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

Язык ассемблера на один уровень выше машинного языка. Он использует короткие мнемонические коды для инструкций и позволяет программисту вводить имена для блоков памяти, которые содержат данные. Таким образом, вместо «0110101100101000» можно написать «добавить оплату, всего» для инструкции, которая складывает два числа.

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

Алгоритмические языки

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

ФОРТРАН

Первым важным алгоритмическим языком был FORTRAN (formula translation), разработанный в 1957 году группой IBM под руководством Джона Бэкуса. Он был предназначен для научных вычислений с вещественными числами и их коллекциями, организованными в виде одномерных или многомерных массивов. Его управляющие структуры включали условные операторы IF, повторяющиеся циклы (так называемые циклы DO) и оператор GOTO, который допускал непоследовательное выполнение программного кода. FORTRAN упростил использование подпрограмм для общих математических операций и создал их библиотеки.

FORTRAN также был разработан для перевода на эффективный машинный язык. Он сразу стал успешным и продолжает развиваться.

АЛГОЛ

АЛГОЛ (алгоритмический, lязык) был разработан комитетом американских и европейских ученых-компьютерщиков в 1958–1960 годах для публикации алгоритмов, а также для выполнения вычислений. Подобно LISP (описанному в следующем разделе), ALGOL имел рекурсивные подпрограммы — процедуры, которые могли вызывать сами себя для решения проблемы, сводя ее к меньшей задаче того же типа. Алгол представил блочную структуру, в которой программа состоит из блоков, которые могут содержать как данные, так и инструкции и иметь ту же структуру, что и вся программа. Блочная структура стала мощным инструментом для создания больших программ из небольших компонентов.

ALGOL предоставил нотацию для описания структуры языка программирования, форму Бэкуса-Наура, которая в некоторых вариантах стала стандартным инструментом для определения синтаксиса (грамматики) языков программирования. Алгол широко использовался в Европе и в течение многих лет оставался языком, на котором публиковались компьютерные алгоритмы. Его потомками являются многие важные языки, такие как Паскаль и Ада (оба описаны ниже).

Язык программирования C был разработан в 1972 году Деннисом Ритчи и Брайаном Керниганом в корпорации AT&T для программирования компьютерных операционных систем. Его способность структурировать данные и программы посредством составления более мелких единиц сравнима с возможностями Алгола. Он использует компактную запись и предоставляет программисту возможность оперировать как с адресами данных, так и с их значениями. Эта способность важна в системном программировании, и язык C разделяет с языком ассемблера способность использовать все возможности внутренней архитектуры компьютера. C, наряду с его потомком C++, остается одним из самых распространенных языков.

Бизнес-ориентированные языки

КОБОЛ

COBOL (комоно, ббизнес, оориентированный яязык) активно использовался предприятиями с момента его в 1959 году. Комитет производителей и пользователей компьютеров и правительственных организаций США учредил CODASYL (Комитет по Данныета, системы и языков) для разработки языкового стандарта и контроля за ним, чтобы обеспечить его переносимость между различными системами.

COBOL использует нотацию, похожую на английскую, но новую при введении. Бизнес-вычисления организуют и обрабатывают большие объемы данных, и COBOL представил структуру данных записи для таких задач.Запись объединяет разнородные данные, такие как имя, идентификационный номер, возраст и адрес, в единый элемент. Это контрастирует с научными языками, в которых распространены однородные массивы чисел. Записи — это важный пример «объединения» данных в единый объект, и они есть почти во всех современных языках.

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

Дэниел создал высокопроизводительные приложения на C++ для крупных компаний, таких как Dreamworks. Он также преуспевает в C и ASM (x86).

Многие из существующих сегодня проектов C были начаты несколько десятилетий назад.

Разработка операционной системы UNIX началась в 1969 году, а ее код был переписан на C в 1972 году. Фактически язык C был создан для переноса кода ядра UNIX с ассемблера на язык более высокого уровня, который выполнял бы те же задачи с меньшими затратами. строки кода.

Разработка базы данных Oracle началась в 1977 году, а ее код был переписан с ассемблера на C в 1983 году. Она стала одной из самых популярных баз данных в мире.

В 1985 году была выпущена Windows 1.0. Хотя исходный код Windows не является общедоступным, было заявлено, что его ядро ​​​​в основном написано на C, а некоторые части находятся на ассемблере. Разработка ядра Linux началась в 1991 году, и оно также написано на C. В следующем году оно было выпущено под лицензией GNU и использовалось как часть операционной системы GNU. Сама операционная система GNU была запущена с использованием языков программирования C и Lisp, поэтому многие ее компоненты написаны на C.

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

Как мир работает на C?

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

Майкрософт Windows

Ядро Microsoft Windows разработано в основном на языке C, а некоторые части — на ассемблере. На протяжении десятилетий самая используемая операционная система в мире, на долю которой приходится около 90 % рынка, работает на ядре, написанном на C.

Линукс

Linux также написан в основном на C с некоторыми частями на ассемблере. Около 97 процентов из 500 самых мощных суперкомпьютеров мира работают под управлением ядра Linux. Он также используется во многих персональных компьютерах.

Компьютеры Mac также работают на C, поскольку ядро ​​OS X написано в основном на C. Каждая программа и драйвер на Mac, как и на компьютерах с Windows и Linux, работают на ядре C.

Мобильный

Ядра iOS, Android и Windows Phone также написаны на C. Они представляют собой просто мобильные адаптации существующих ядер Mac OS, Linux и Windows. Итак, смартфоны, которыми вы пользуетесь каждый день, работают на ядре C.

Базы данных

Самые популярные в мире базы данных, в том числе Oracle Database, MySQL, MS SQL Server и PostgreSQL, написаны на C (первые три из них на самом деле и на C, и на C++).

Базы данных используются во всех типах систем: финансовых, правительственных, медиа, развлекательных, телекоммуникационных, медицинских, образовательных, розничных, социальных, веб- и т. д.

3D-фильмы

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

Встроенные системы

Представьте, что однажды вы просыпаетесь и идете за покупками. Будильник, который будит вас, вероятно, запрограммирован на C. Затем вы используете микроволновую печь или кофеварку, чтобы приготовить себе завтрак. Они также являются встроенными системами и поэтому, вероятно, запрограммированы на C. Вы включаете телевизор или радио во время завтрака. Это также встроенные системы, работающие на C. Когда вы открываете дверь гаража с помощью пульта дистанционного управления, вы также используете встроенную систему, которая, скорее всего, запрограммирована на C.

Затем вы садитесь в машину. Если он имеет следующие функции, также запрограммированные на C:

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

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

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

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

Почему до сих пор используется язык программирования C?

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

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

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

Портативность и эффективность

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

Его переносимость и эффективность настолько высоки, что «компиляторы, библиотеки и интерпретаторы других языков программирования часто реализуются на C». Интерпретируемые языки, такие как Python, Ruby и PHP, имеют свои основные реализации, написанные на C. Он даже используется компиляторами других языков для связи с машиной. Например, C является промежуточным языком, лежащим в основе Eiffel и Forth. Это означает, что вместо того, чтобы генерировать машинный код для каждой поддерживаемой архитектуры, компиляторы для этих языков просто генерируют промежуточный код C, а компилятор C обрабатывает генерацию машинного кода.

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

Манипулирование памятью

Доступ к произвольным адресам памяти и арифметические операции с указателями — важная функция, благодаря которой C идеально подходит для системного программирования (операционные системы и встроенные системы).

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

Микроконтроллер можно спроектировать, например, так, чтобы байт в памяти с адресом 0x40008000 был отправлен универсальным асинхронным приемником/передатчиком (или UART, общим аппаратным компонентом для связи с периферийными устройствами). каждый раз, когда бит номер 4 адреса 0x40008001 устанавливается в 1, и что после того, как вы установите этот бит, он будет автоматически сбрасываться периферийным устройством.

Это будет код для функции C, которая отправляет байт через этот UART:

Первая строка функции будет расширена до:

Эта строка указывает компилятору интерпретировать значение 0x40008000 как указатель на char , затем разыменовать (дать значение, на которое указывает) этот указатель (с крайним левым оператором *) и, наконец, присвоить байтовое значение этому разыменованному указателю. .Другими словами: запишите значение переменной byte по адресу памяти 0x40008000 .

Следующая строка будет расширена до:

В этой строке мы выполняем побитовую операцию ИЛИ над значением по адресу 0x40008001 и значением 0x08 (00001000 в двоичном формате, т. е. 1 в бите номер 4) и сохраняем результат обратно по адресу 0x40008001. Другими словами: мы устанавливаем бит 4 байта, который находится по адресу 0x40008001. Мы также объявляем, что значение по адресу 0x40008001 является изменчивым. Это сообщает компилятору, что это значение может быть изменено процессами, внешними по отношению к нашему коду, поэтому компилятор не будет делать никаких предположений о значении в этом адресе после записи в него. (В данном случае этот бит сбрасывается аппаратно UART сразу после того, как мы устанавливаем его программно.) Эта информация важна для оптимизатора компилятора. Если бы мы сделали это внутри цикла for, например, не указав, что значение является изменчивым, компилятор мог бы предположить, что это значение никогда не изменяется после установки, и пропустить выполнение команды после первого цикла.

Детерминированное использование ресурсов

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

Размер кода

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

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

Исключения — это отличный инструмент, добавленный C++ поверх C, и, если их не запускать и правильно реализовывать, они практически не требуют дополнительных затрат времени на выполнение (но за счет увеличения размера кода).

Давайте рассмотрим пример на C++:

Методы классов A , B и C определены где-то еще (например, в других файлах). Поэтому компилятор не может их анализировать и не может знать, вызовут ли они исключения. Поэтому он должен быть готов к обработке исключений, вызванных любым из их конструкторов, деструкторов или вызовов других методов. Деструкторы не должны генерировать исключение (очень плохая практика), но пользователь все равно может генерировать исключение, или они могут вызывать генерацию косвенно, вызывая какую-либо функцию или метод (явно или неявно), которые генерируют исключение.

Если какой-либо из вызовов в myFunction вызывает исключение, механизм раскрутки стека должен иметь возможность вызывать все деструкторы для уже созданных объектов. Одна реализация механизма раскручивания стека будет использовать адрес возврата последнего вызова этой функции для проверки «номера контрольной точки» вызова, вызвавшего исключение (это простое объяснение). Он делает это, используя вспомогательную автоматически сгенерированную функцию (своего рода справочную таблицу), которая будет использоваться для раскручивания стека в случае возникновения исключения из тела этой функции, которое будет похоже на это:

Если исключение выдается из контрольных точек 1 и 9, уничтожение объектов не требуется. Для контрольной точки 3 b и a должны быть уничтожены. Для контрольной точки 6, c и a должны быть уничтожены. Во всех случаях порядок уничтожения должен соблюдаться. Для контрольных точек 2, 4, 5, 7 и 8 необходимо уничтожить только объект a.

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

И мы говорим о C++, языке, принцип которого гласит: «Вы не платите за то, чем не пользуетесь». Это увеличение размера двоичного файла усугубляется для других языков, которые добавляют дополнительные накладные расходы с другими функциями, которые очень полезны, но не могут быть предоставлены встроенными системами. Хотя C не дает вам возможности использовать эти дополнительные функции, он обеспечивает гораздо более компактный размер кода, чем другие языки.

Причины изучения C

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

Лингва франка

Как уже упоминалось, C — это язык межнационального общения для разработчиков.Многие реализации новых алгоритмов в книгах или в Интернете впервые (или только) доступны на языке C их авторами. Это дает максимально возможную переносимость реализации. Я видел, как программисты пытались в Интернете переписать алгоритм C на другие языки программирования, потому что они не знали самых основных концепций C.

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

Понимание машины (думай на C)

Когда мы обсуждаем поведение определенных частей кода или определенных функций других языков с коллегами, мы заканчиваем тем, что «говорим на C»: эта часть передает «указатель» на объект или копирует весь объект? Мог ли здесь происходить какой-то «каст»? И так далее.

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

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

Работа над многими интересными проектами на C

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

Заключение

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

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

Читайте также: