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

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

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

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

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

22.08.2008 14:29:27
Ваша книга - второе издание K & R; когда упоминается K & R C, это означает C, описанный в первом издании (который служил своего рода стандартом до появления стандарта ANSI, к тому времени язык довольно сильно разошелся).
vonbrand 1.02.2013 20:28:39
11 ОТВЕТОВ
РЕШЕНИЕ

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

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

29
26.08.2013 13:43:02
Первое издание K & R было опубликовано в 1978 году. Язык Си сильно изменился в период с 1969 по 1978 год.
Keith Thompson 23.08.2013 22:22:39
Сэр, я добавил часть в ваш ответ, поскольку я не был уверен, смогу ли я добавить его в качестве другого ответа, вы можете удалить его. Что вы скажете по этому поводу?
Suraj Jain 17.02.2017 08:05:38

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

1
22.08.2008 14:31:19

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

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

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

12
22.08.2008 14:35:12
Строго говоря, по определению «прототип» - это объявление функции с явно типизированными параметрами. Эти старые декларации в стиле K & R были / не являются прототипами.
AnT 27.10.2009 13:53:55
Это не действительно K & R :) Это пошло бы int p; float q; double r;илиint p, q, r;
Seva Alekseyev 5.07.2016 23:02:18

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

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

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

16
28.08.2008 03:15:27

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

f(x)
{
    return x + 1;
}

и

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

идентичны

3
11.09.2008 01:23:11
ANSI C по-прежнему допускает типизацию int по умолчанию.
Corey D 2.09.2009 16:34:41

Разница в том, что:

  1. Прототип
  2. широкая поддержка персонажей и интернационализация
  3. Поддержка постоянных и изменчивых ключевых слов
  4. разрешить использование указателей на функции в качестве разыменования
2
31.10.2011 11:50:25
  1. прототип функции.
  2. постоянные и изменчивые классификаторы.
  3. широкая поддержка персонажей и интернационализация.
  4. разрешить использование указателя на функцию без разыменования.
7
31.10.2011 11:51:39
  • ПРОТОТИПИРОВАНИЕ ФУНКЦИЙ: ANSI C принимает метод прототипа функции c ++, где определение функции и объявление включают имена функций, аргументы t, типы данных и возвращаемые значения. Типы функций. Прототип функции позволяет компиляторам ANSI проверять вызов функции в программе пользователя, которая передает недопустимый номер аргумента. или несовместимые типы данных аргументов. Это исправляет серьезную слабость компиляторов K & R: неправильный вызов в пользовательской программе часто проходит компиляцию, но вызывает сбой программы при их выполнении.
2
4.06.2011 15:46:19

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

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

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

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

 unsigned long foo (char* fmt, double data)
 {
      /*body of foo */
 }
2
17.02.2015 14:32:34

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

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

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

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

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

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

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

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

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

2
5.07.2016 22:58:48
Сэр, мне нужно поговорить с вами по этому вопросу, так как я планирую начать K & R 2nd Ed. Мы можем поговорить?
Suraj Jain 17.02.2017 07:15:51
@SurajJain: если вы откроете сеанс чата, я постараюсь ответить, как могу.
supercat 17.02.2017 16:41:17

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

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

-1
5.01.2017 21:47:58
Язык, определенный во второй книге, намного лучше, чем C89, поскольку K & R исключил правила псевдонимов, которые делают язык совершенно непригодным для использования в системном программировании. Правила, которые позволяли компиляторам предполагать, что указатели не будут псевдонимами других типов в тех случаях, когда компилятор не будет иметь никаких оснований ожидать, что они это сделают, могут быть разумными, но авторы компиляторов утверждают, что сегодняшние ужасные правила - не более чем " разъяснение "правил C89.
supercat 9.01.2017 21:55:00