поправьте меня, если мое понимание c неверно

#c #c

#c #c

Вопрос:

поправьте меня, если какое-либо из моих следующих текущих представлений о c неверно:

  1. C — это расширенная версия C. Следовательно, C так же эффективен, как C.
  2. Более того, любое приложение, написанное на C, может быть скомпилировано с использованием компиляторов C
  3. Синтаксис C также является допустимым синтаксисом C
  4. C находится в той же иерархии языкового уровня, что и C.

Иерархия уровня языка

например. самый низкий уровень: язык ассемблера, высокие уровни: Java, PHP и т. Д

итак, моя интерпретация такова

C / C находится на более низком уровне, чем Java, PHP и т.д., Поскольку он ближе к аппаратному уровню (и, следовательно, из-за этого он более эффективен, чем Java, PHP и т.д.), Но он не такой экстремальный, как язык ассемблера …. но C / C находятся на одном уровне друг с другом, и ни один из них не ближе к аппаратному уровню

Комментарии:

1. @Heandel: По сравнению с чем? Эквивалентная программа на C имеет ту же производительность.

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

3. @Heandel: Да, возможно. (На самом деле, JIT-программы, как правило, превосходят собственные программы.) В любом случае, я прошу разъяснений, а не остроумного ответа. Как вы определяете, что есть накладные расходы? Как вы проводите измерения? Что вы измеряете? Накладные расходы по сравнению с некоторым эквивалентным поведением, или вопрос бессмыслен.

4. @Heandel: Да, но если вам нужна динамическая отправка, то указывать на ее стоимость довольно банально. Не имеет значения, сколько что-то стоит, если вам нужно его поведение. Итак, еще раз: накладные расходы, измеряемые чем по сравнению с чем? Вы сказали, что виртуальные методы имеют накладные расходы, я хочу знать, по сравнению с чем. Я хочу знать, какой смысл в вашем первом комментарии.

5. @Heandel Вы упускаете из виду точку зрения GMan: если вы пишете графический редактор, который рисует объекты (квадраты, точки, изображения …), то какой бы дизайн вы ни выбрали, вы должны использовать динамическую отправку или имитировать ее менее эффективным способом.

Ответ №1:

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

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

  3. Смотрите 2 — некоторые синтаксические C не будут работать как C . Как уже отмечалось, преобразование обычно тривиально.

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

Ответ №2:

C находится в той же иерархии уровня языка, что и иерархия уровня языка C. например. самый низкий уровень: язык ассемблера, высокие уровни: Java, PHP и т. Д

Языки программирования часто подразделяются на 1-е поколение (машинный код), 2-е поколение (язык ассемблера), 3-е поколение (императивные языки), 4-е поколение (определение немного расплывчатое — языки, специфичные для конкретной области, предназначенные для высокой производительности, например SQL), 5-е поколение (типичный язык выражения проблемы, например, математическая нотация, логика или человеческий язык; Miranda, Prolog). Смотрите, например http://en.wikipedia.org/wiki/Fifth-generation_programming_language и его ссылки.

В этом смысле C и C оба являются языками 3-го поколения. (Как указывает Джерри, то же самое относится к PHP, Java, PERL, Ruby, C # …). Используя этот критерий, эти языки принадлежат к одной общей группе … это все языки, на которых вы должны сообщить компьютеру, как решить проблему, но не на уровне, зависящем от процессора.

С другой стороны, C имеет концепции программирования более высокого уровня, чем C, такие как объектная ориентация, функторы и более полиморфные функции, включая шаблоны и перегрузку, хотя все они представляют собой способы организации шагов для решения проблемы и доступа к ним. Языкам более высокого уровня (т. Е. 5GL) не нужно об этом говорить — скорее, им просто нужно описание проблемы и знание того, как решить всю область проблем, чтобы они нашли работоспособный подход для вашего конкретного случая.

C / C находится на более низком уровне, чем Java, PHP и т.д., Поскольку он ближе к аппаратному уровню (и, следовательно, из-за этого он более эффективен, чем Java, PHP и т.д.), Но он не такой экстремальный, как язык ассемблера …. но C / C находятся на одном уровне друг с другом, и ни один из них не ближе к аппаратному уровню

Это немного сбивает с толку. Вкратце:

  • C и Си имеют меньший охват, чем Java / PHP, да.
  • C и Си, как правило, более эффективны, да. Вы можете получить общее представление об этом на http://benchmarksgame.alioth.debian.org/u64q/which-programs-are-fastest.html — не воспринимайте это слишком буквально, это во многом зависит от вашего проблемного пространства.
  • C и C оба идут так же низко, как и другие, но C также имеет некоторую поддержку программирования более высокого уровня (хотя это все еще 3GL, как C).

Давайте рассмотрим несколько примеров:

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

  • C предоставляет некоторые средства более высокого уровня, такие как шаблоны (и, следовательно, метапрограммирование шаблонов) и множественное наследование. Компиляторы обычно предоставляют низкоуровневые средства, такие как встроенная сборка и возможность вызывать произвольные функции из других объектов / библиотек, если сигнатуры функций известны во время компиляции (некоторые библиотеки обходят это ограничение). Интерпретируемые (например, PHP) и основанные на виртуальных машинах (например, Java) языки, как правило, хуже справляются с этим.

  • Java также предоставляет некоторые возможности более высокого уровня, которых не хватает C — например, самоанализ, сериализация.

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

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

C — это расширенная версия C. Следовательно, C так же эффективен, как C.

В целом верно.

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

Есть некоторые тривиальные различия, например:

  • в C main() должен иметь возвращаемый тип int и неявно возвращает 0 при выходе, если оператор return не встречается, но C допускает void or int , и для последнего должно быть явно возвращено int
  • В C есть дополнительные ключевые слова (например, mutable , virtual , class explicit ,,, …), которые, следовательно, не являются законными идентификаторами C , но являются законными в C

Тем не менее, ваша концепция по сути верна.

Комментарии:

1. @Jerry: справедливый вызов — я пытался прояснить это подробнее. Приветствия.

2. выглядит намного лучше (по крайней мере, для меня).

Ответ №3:

1/4 и 2/3, похоже, говорят очень похожие вещи, но:

  1. Да (зависит от того, что вы подразумеваете под «расширенным», но на широком уровне, да)
  2. Не всегда
  3. Не всегда
  4. ДА

Ответ №4:

Более того, любое приложение, написанное на C, может быть скомпилировано с использованием компиляторов C

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

C — это расширенная версия C. Следовательно, C так же эффективен, как C.

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

Комментарии:

1. Ваш первый пункт неверен, это не может быть скомпилировано на C . «char* c = malloc(10);»

2. Хм, я думал, что сказал именно это. Возможно, мне следует изменить форматирование. Выделенные жирным шрифтом предложения просто скопированы из вопроса.

Ответ №5:

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

  2. Нет, большой случай заключается в том, что C не поддерживает автоматическое приведение из void * так, например

    char * c = malloc(10); // Допустим C, но не C

    в C требуется char * c = (char *)malloc(10) //

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

  4. Не могли бы вы пояснить, что вы подразумеваете под этим, что вы подразумеваете под «иерархией уровня языка»?

Ответ №6:

Краткие сведения:

  1. Верно.
  2. Опасно ложный.
  3. Ложь.
  4. Субъективный

Несколько примеров для 2/3:

  • sizeof 'a' равно 1 в C и sizeof(int) в C.
  • char *s = malloc(len 1); правильный C, но недопустимый C .
  • char s[2*strlen(name) 1]; допустимый (хотя и опасный) C, но недопустимый C .
  • sizeof (1?"hello":"goodbye") is sizeof(char *)` в C, но 6 в C .

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

Ответ №7:

Ваше понимание неверно в некоторых ваших пунктах:

1) ваш первый пункт верен.C является расширением c.

2) второй момент правильный. C может быть скомпилирован с использованием компиляторов c .

3) Некоторые синтаксические особенности C отличаются от c . В c , используя structure , c должен указывать имя структуры, но c указывать имя структуры не обязательно.Также в C есть концепция класса, которая недоступна в c. C также имеет более высокие механизмы безопасности.

4) C — процедурный язык, но c — объектно-ориентированный подход. таким образом, c не находится в той же иерархии языкового уровня, что и c.

Ответ №8:

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

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

  3. Нет, эволюция этих языков отличается. Смотрите ответ на вопрос 1.

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

Ответ №9:

Это целый большой вопрос, на который нужно ответить.

  1. Не во всех случаях!
  2. неверно из-за 3
  3. неверно
  4. Они не совсем одинаковы

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