关于ANSI C维基百科文章说:

ANSI C标准化过程的目标之一是生成K&R C(第一个发布的标准)的超集,其中包含随后引入的许多非官方特征。 但是,标准委员会还包括一些新功能,例如函数原型(借用C ++编程语言)和更强大的预处理器。 参数声明的语法也已更改,以反映C ++样式。

这让我觉得有差异。 但是,我没有看到K&R C和ANSI C之间的比较。是否有这样的文件? 如果没有,主要区别是什么?

编辑:我相信K&R书的封面上写着“ANSI C”。 至少我相信我在家里的版本确实如此。 那么也许没有什么区别了?

===============>>#1 票数:29 已采纳

关于“K&R C”是什么,这里可能存在一些混淆。 该术语指的是第一版“C程序设计语言”中记录的语言。 粗略地说:贝尔实验室C编译器的输入语言大约是1978年。

Kernighan和Ritchie参与了ANSI标准化过程。 “ANSI C”方言取代了“K&R C”,后续版本的“C编程语言”采用ANSI惯例。 “K&R C”是一种“死语言”,除非某些编译器仍然接受遗留代码。

===============>>#2 票数:16

功能原型是K&R C和C89之间最明显的变化,但还有很多其他的。 许多重要的工作也用于标准化C库。 尽管标准C库是对现有实践的编纂,但它编纂了多种现有实践,这使其更加困难。 PJ Plauger的书, 标准C库 ,是一个很好的参考,并且还讲述了为什么图书馆以它的方式结束的幕后细节。

ANSI / ISO标准C在很多方面与K&R C非常相似。 它的目的是大多数现有的C代码应该在ANSI编译器上构建而不需要很多更改。 然而,至关重要的是,在预标准时代,语言的语义可供每个编译器供应商解释。 ANSI C引入了语言语义的通用描述,使所有编译器处于平等的地位。 现在,大约20年后,这很容易被视为理所当然,但这是一项重大成就。

在大多数情况下,如果您没有预先标准的C代码库来维护,您应该很高兴您不必担心它。 如果你这样做 - 或者更糟糕的是,如果你想把一个旧的程序带到更现代的标准 - 那么你会有我的同情心。

===============>>#3 票数:12

虽然有一些细微的差别,但我认为K&R的后期版本适用于ANSI C,因此不再存在真正的差异。
由于缺乏更好的术语,“C Classic”的定义函数的方式略有不同,即

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

我相信另一个区别是功能原型。 原型不必 - 实际上他们不能 - 采取一系列参数或类型。 在ANSI C中他们这样做。

===============>>#4 票数:6

  1. 功能原型。
  2. 常量和挥发性限定符。
  3. 广泛的人格支持和国际化。
  4. 允许函数指针在没有解除引用的情况下使用。

===============>>#5 票数:3

另一个区别是函数返回类型和参数类型不需要定义。 他们将被认为是整体。

f(x)
{
    return x + 1;
}

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

是相同的。

===============>>#6 票数:2

ANSI C和K&R C之间的主要区别如下:

  • 功能原型
  • 支持const和volatile数据类型限定符
  • 支持广泛的人物和国际化
  • 允许在不解除引用的情况下使用函数指针

ANSI C采用c ++函数原型技术,其中函数定义和声明包括函数名,参数'数据类型和返回值数据类型。 函数原型使ANSI C编译器能够在用户程序中检查传递无效数量的参数或不兼容的参数数据类型的函数调用。 这些修复了K&R C编译器的主要缺点。

示例:声明函数foo并要求foo接受两个参数

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

===============>>#7 票数:2

不同之处是:

  1. 原型
  2. 广泛的人格支持和国际化
  3. 支持const和volatile关键字
  4. 允许函数指针用作解除引用

===============>>#8 票数:2

  • 功能原型:ANSI C采用c ++函数原型技术,其中函数definaton和声明包括函数名,参数t,数据类型和返回值数据类型。函数原型启用ANSI ccompilers检查用户程序中的函数调用,该函数调用传递了无效的参数号或不兼容的参数数据类型。这解决了K&R C编译器的一个主要缺点:用户程序中的无效调用经常通过编译但导致程序在执行时崩溃

===============>>#9 票数:1

我认为,最大的单一差异是函数原型和用于描述函数参数类型的语法。

===============>>#10 票数:1

没有人提到的一个主要区别是,在ANSI之前,C主要是由先例而不是规范来定义的; 如果某些操作会对某些平台产生可预测的后果而不会影响其他平台(例如,在两个不相关的指针上使用关系运算符),则先例强烈支持为程序员提供平台保证。 例如:

  1. 在定义所有对象的所有指针中的自然排名的平台上,可以依赖于将关系运算符应用于任意指针以产生该排名。

  2. 在测试一个指针是否“大于”另一个指针的自然方法的平台上除了产生真值或假值之外从未产生任何副作用,同样可以依赖关系运算符应用于任意指针永远不会有任何一方 - 产生真或假值以外的影响。

  3. 在两个或多个整数类型共享相同大小和表示的平台上,可以依赖指向任何此类整数类型的指针来读取或写入具有相同表示的任何其他类型的信息。

  4. 在二进制补码平台上,整数溢出自然地静默包装,可以依赖一个涉及小于“int”的无符号值的操作,就好像在结果介于INT_MAX + 1u和UINT_MAX之间的值是无符号的那样未被提升为更大的类型,也不用作>>的左操作数,也不用作/%或任何比较运算符的操作数。 顺便提一下,标准的基本原理将此作为小型无符号类型促进签名的原因之一

在C89之前,尚不清楚上述假设不会自然持有的平台编译器的长度,无论如何都可能会维持这些假设,但毫无疑问,平台的编译器可以轻松而廉价地维护这些假设应该这样做。 C89标准的作者没有明确说明这一点,因为:

  1. 编写者并非故意使用的编译器会在实际操作时继续执行此类操作,而不必被告知(为签署小型无符号值而提出的理由强烈强调了这一观点)。

  2. 标准只要求实现能够在没有堆栈溢出的情况下运行一个可能设计的程序,并且认识到虽然一个钝的实现可以将任何其他程序视为调用未定义的行为但是并不认为值得担心编译器编写者的写作实现“符合”但无用的。

虽然“C89”被同时解释为“C89定义的语言,加上平台提供的任何其他功能和保证”,但gcc的作者一直在推动一种解释,其排除了C89规定的任何特征和保证。

===============>>#11 票数:-1

尽管对K&R的所有要求都是并且能够提供任何类型的东西,从靠近硬件的低位向上提供。 现在的问题是找到一个编译器(最好是免费的),它可以在几百万行K&R C上进行干净的编译,而不必捣乱它。并在像AMD多核处理器这样的东西上运行。

据我所知,看过GCC 4.xx系列的来源,没有简单的黑客重新激活-traditional和-cpp-traditional滞后功能到他们之前的工作状态,而不是没有比我预先设定的更多的effor放入。并且更容易从头开始构建K&R pre-ansi编译器。

  ask by Thomas Owens translate from so

未解决问题?本站智能推荐: