Каковы основные различия между ANSI C и K&R C?

StackOverflow https://stackoverflow.com/questions/22500

  •  09-06-2019
  •  | 
  •  

Вопрос

А Статья в Википедии об ANSI C говорит:

Одной из целей процесса стандартизации ANSI C было создание расширенного набора K&R C (первого опубликованного стандарта), включающего многие неофициальные функции, представленные впоследствии.Однако комитет по стандартизации также включил несколько новых функций, таких как прототипы функций (заимствованные из языка программирования C++) и более функциональный препроцессор.Синтаксис объявлений параметров также был изменен, чтобы отразить стиль C++.

Это заставляет меня думать, что различия есть.Однако я не видел сравнения между K&R C и ANSI C.Есть ли такой документ?Если нет, то каковы основные различия?

РЕДАКТИРОВАТЬ:Я думаю, что в книге K&R на обложке написано «ANSI C».По крайней мере, я верю в ту версию, которая есть у меня дома.Так может быть, разницы уже нет?

Это было полезно?

Решение

Здесь может возникнуть некоторая путаница относительно того, что такое «K&R C».Термин относится к языку, как зарегистрировано в первом издании «Язык программирования С». Грубо говоря:язык ввода компилятора C Bell Labs примерно в 1978 году.

Керниган и Ритчи участвовали в процессе стандартизации ANSI.Диалект «ANSI C» заменил «K&R C», и последующие издания «Языка программирования C» приняли соглашения ANSI.«K&R C» — «мертвый язык», за исключением того, что некоторые компиляторы все еще принимают устаревший код.

Другие советы

Функциональные прототипы были наиболее очевидным изменением между K&R C и C89, но было и множество других.Много важной работы было потрачено и на стандартизацию библиотеки C.Несмотря на то, что стандартная библиотека C была кодификацией существующей практики, она систематизировала несколько существующей практики, что усложняло задачу.ПиДжейКнига Плаугера, Стандартная библиотека C, является отличным справочником, а также рассказывает некоторые закулисные детали почему библиотека закончилась так, как сложилась.

Стандарт C ANSI/ISO во многом похож на K&R C.Предполагалось, что большая часть существующего кода C должна основываться на компиляторах ANSI без особых изменений.Однако важно отметить, что в эпоху до появления стандартов семантика языка была открыта для интерпретации каждым поставщиком компилятора.ANSI C ввел общее описание семантики языка, которое поставило все компиляторы в равные условия.Сейчас, примерно 20 лет спустя, это легко принять как должное, но это было значительное достижение.

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

Есть некоторые незначительные различия, но я думаю, что более поздние выпуски K&R предназначены для ANSI C, поэтому реальной разницы больше нет.
«C Classic» из-за отсутствия лучших терминов имел несколько иной способ определения функций, т.е.

int f( p, q, r )  
int p, float q, double r;  
{  
    // Code goes here  
}

Я считаю, что еще одним отличием были прототипы функций.Прототипам не обязательно (фактически они и не могли) принимать список аргументов или типов.В ANSI C они есть.

  1. прототип функции.
  2. постоянные и изменчивые квалификаторы.
  3. широкая поддержка персонажей и интернационализация.
  4. разрешить использование указателя функции без разыменования.

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

f(x)
{
    return x + 1;
}

и

int f(x)
int x;
{
    return x + 1;
}

идентичны.

  • ПРОТОТИПИРОВАНИЕ ФУНКЦИИ: ANSI C использует технику прототипа функции C++, где определение и объявление функции включают имена функций, аргументы t, типы данных и типы возвращаемых значений. Прототип функции позволяет компиляторам ANSI проверять вызов функции в пользовательской программе, которая передает недопустимое число число аргументов. или несовместимые типы данных аргументов. Они устраняют основную слабость компиляторов K&R C: неверный вызов в пользовательской программе часто проходит компиляцию, но приводит к сбою программы при их выполнении.

Разница в следующем:

  1. Опытный образец
  2. широкая поддержка персонажей и интернационализация
  3. Поддержка константных и изменчивых ключевых слов.
  4. разрешить использование указателей функций для разыменования

Основные различия между ANSI C и K&R C заключаются в следующем:

  • прототипирование функций
  • поддержка квалификаторов типов данных const и flaming
  • поддержка широких символов и интернационализации
  • разрешить использование указателей функций без разыменования

ANSI C использует технику прототипа функции C++, где определение и объявление функции включают имена функций, типы данных аргументов и типы данных возвращаемого значения.Прототип функции позволяет компилятору ANSI C проверять вызовы функций в пользовательских программах, которые передают недопустимое количество аргументов или несовместимые типы данных аргументов.Они устраняют основную слабость компилятора K&R C.

Пример:to объявляет функцию foo и требует, чтобы foo принимала два аргумента

 unsigned long foo (char* fmt, double data)
 {
      /*body of foo */
 }

Я думаю, что самое большое отличие — это прототипирование функций и синтаксис описания типов аргументов функций.

Основное отличие, о котором никто еще не упомянул, заключается в том, что до ANSI язык C определялся в основном на основании прецедента, а не спецификации;в случаях, когда определенные операции будут иметь предсказуемые последствия на некоторых платформах, но не на других (например.использование реляционных операторов для двух несвязанных указателей), прецедент настоятельно рекомендовал сделать гарантии платформы доступными для программиста.Например:

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

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

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

  4. На платформах с дополнением до двух, где целочисленные переполнения естественным образом переносятся автоматически, можно полагаться на то, что операция, включающая беззнаковые значения, меньшие, чем «int», будет вести себя так, как если бы значение было беззнаковым, в тех случаях, когда результат будет между INT_MAX+1u и UINT_MAX, и это не был повышен до более крупного типа и не использовался в качестве левого операнда >>, ни один из операндов /, %, или любой оператор сравнения. Между прочим, в обосновании стандарта это рассматривается как одна из причин, по которой небольшие беззнаковые типы превращаются в подписанные..

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

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

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

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

Несмотря на все претензии к обратному, K&R была и вполне способна предоставлять любые вещи, начиная от низшего уровня и заканчивая аппаратным обеспечением.Проблема сейчас состоит в том, чтобы найти компилятор (желательно бесплатный), который сможет выполнить чистую компиляцию пары миллионов строк K&R C, не заморачиваясь с ним. И работающий на чем-то вроде многоядерного процессора AMD.

Насколько я понимаю, посмотрев исходный код серии GCC 4.x.x, не существует простого способа реактивировать функциональность -traditional и -cpp-traditional lag в их предыдущее рабочее состояние без дополнительных усилий, чем я готов Путин.И проще создать пре-анси-компилятор K&R с нуля.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top