学生学习哪个版本的C语言更合适 - C89/90还是C99?

20

我打算在下个月开始学习系统编程之前学习C语言基础和语法。在阅读一些资料时,我了解到C89/99标准。根据维基百科的说法,

C99引入了一些新特性,包括内联函数、若干新的数据类型(包括long long int和一个表示复数的复数类型)、可变长度数组、支持可变参数宏(可变元数的宏)以及支持以//开头的单行注释,就像BCPL或C ++中的注释。其中很多已经作为扩展实现在多个C编译器中。

C99在大部分情况下与C90向后兼容,但在某些方面更为严格;特别是,缺少类型说明符的声明不再隐含地假定为int。一个名为STDC_VERSION的标准宏定义了值199901L,以表示支持C99。GCC、Sun Studio和其他编译器现在支持C99的许多或全部新功能。

我借了一本K&R第二版的书,它使用C89标准。对于一名学生来说,使用C89会使K&R涵盖的某些主题无效吗?如果有的话,我应该注意哪些问题?

8个回答

19

学习C99比学习C89或C90更为合理,因为它已经完全取代了前两者。C99编译器易于获取,并且没有任何理由去学习早期的标准。

这并不意味着你的教授不会强制让你学习C89。从这里发布的各种标记为作业的问题中可以感受到,很多C(不幸的是,还有C++)课程仍然停留在C89。

对于一个刚开始学习的学生来说,你可能不会真正注意到差异-有很多既是C99又是C89/90的内容需要掌握。


9
很容易找到C99编译器,但GCC仍需要使用“-std=c99”标志,而微软显然不正确地支持它。http://stackoverflow.com/questions/2656080/vs-2008-and-c99 - Fred Foo
1
@larsmans:所以,GCC完全支持它,并且有数十个可用于Windows的C编译器。至于微软,如果你有一个C++编译器,回到C就疯了,所以他们缺乏对C99的支持并不是什么大问题。 - Puppy
2
很好,答案加1。虽然我不同意“回到”C是一个疯狂的举动。作为一名C++程序员,我仍然喜欢C语言的极简主义。 - Fred Foo
2
@DeadMG:GCC并不完全支持C99,存在一些省略(通常可以忽略,但在某些平台上比其他平台更糟糕)。 - Steve Jessop
1
关于“回溯”,如果您在意代码的效率和安全性,C++相比C语言有一些有用的特性,但也存在很多烦恼,尤其是对类型强制执行的疯狂方法和需要显式转换的必要性。 - R.. GitHub STOP HELPING ICE
显示剩余9条评论

11

使用C99标准,它是较新且具有更多功能。特别有用的可能是<stdbool.h>中的bool类型和int32_t等类型系列;后者可以防止很多依赖于int具有特定大小的不可移植代码。据我所知,它不会使K&R规范失效,虽然一些示例程序现在可能以稍微不同的风格编写。

请注意,某些编译器仍然无法正确支持C99。我相信GCC仍需要使用-std=c99标志才能启用它;许多Unix/Linux系统都有一个c99命令,它包装了GCC并启用了C99。

对于很多大学教授也是如此。在我的大一时,我用bool编写的程序让我的教授感到惊讶:他从未听说过C语言中的这种类型 :)


1
我在我的个人系统上安装了MinGW。 - Jason

4

虽然我一般同意其他人的观点,但值得注意的是,《C程序设计语言》是一本非常好的书,可能值得从中学习C语言,然后在阅读有关C99标准的内容时更新您的知识。


2
我是唯一一个不认为K&R是学习C语言最好的书籍的人吗?它确实是经典的计算机科学教材,但我不确定它是否适合初学者。最好学习更新的标准和风格。 - in70x

3
如果您处于学生水平,您可能甚至不会注意到差异。

1
C99/C++注释//(u)intN_t,代码后的声明以及printf的%z是一些非常容易注意到的东西。至少如果你没有学习C语言的错误方式的话。 - 12431234123412341234123

2
是的,有点奇怪,你可以得出一个响亮的共识,认为K&R是一本很好的C语言书籍,同时也有一个响亮的共识,认为C99是正确/当前/最好的C语言版本。这两个立场是不兼容的——即使K&R是学习“意味着C99”的最佳书籍,这只意味着其余的书籍要么是垃圾,要么已经过时了。
我建议学习和使用C99,但同时关注C89。如果你使用的编译器具有C89和C99兼容模式,则可以编写一些C89代码,以了解它们之间的区别。然后,如果您需要编写一些旨在可移植到C99无法到达的地方的代码,则会知道该怎么做。如果您从未编写过此类代码,则可能浪费了一天时间。
正确编写C89实际上是非常困难的,因为获取C89标准副本很困难。因此,如果可以,请使用C99;如果由于某种奇怪的原因必须使用C89,则应了解其中的区别。也许可以使用K&R来涵盖基础知识,但尽快查看一些惯用的C99。
至于阅读K&R时要注意的具体问题:标准前言中有一份主要更改列表(http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf),尽管其中没有详细说明。其中很多是添加到C99中的新功能,因此不是K&R错误,而是可能并不总是使用最佳工具进行某项工作。其中一些是相当琐碎的事情,在需要详细了解时可能应该咨询标准。其余的则是从C89中删除的内容,通常当您尝试使用它们时,C99编译器会告诉您相关信息。

1

术语“C89”描述了两种非常不同的语言:

  1. 程序员在1989年认为委员会在标准存在歧义的地方所描述的语言,支持现有实现中常见的功能。

  2. 委员会后来决定要描述的语言,抛弃了与现有功能的兼容性。

C99通过表明他们的意图是让标准以一种方式解释,这将破坏大量现有代码并使许多任务无法像1989年之前使用C那样高效地执行,从而“澄清”了标准的模糊部分。

对于许多应用程序来说,正确的编程语言将是预标准C、C89、C99和C11的超集。然而,重要的是,任何使用该语言进行编程的人都清楚地知道他们正在使用该语言,而不是偏向速度而不是可靠性的缩小子集。


1

作为一名学生,这并不会对你产生太大的影响。但如果可能的话,你应该找一本涵盖C99的新C语言书籍。


1

虽然我认为知道哪些功能是较新的且不太可能被晦涩的(或者像 MSVC 一样故意破坏的)编译器支持是有益的,但有几个 C99 功能是您绝对应该使用的:

  • snprintf:这是C语言中安全和干净的字符串拼接的最终函数。如果你的编译器缺少它,你可以替换整个printf子系统(这可能是一个好主意,因为大多数缺少snprintf的实现也充满了(通常是有意的)printf行为上的错误),或者包装tmpfile/fprintf/fread/fclose

  • stdint.h:如果你需要固定大小的类型(16/32/64位),请使用标准名称int16_tuint16_tint32_t等。不要自己发明,绝对不要使用系统特定的类型,如INT64u32。这只会让你的代码变得丑陋,难以集成和重用。如果你的编译器缺少stdint.h,只需放入你自己的文件来定义正确的平台类型。

  • 具体来说,使用uint64_t代替int foo[2];struct { int lo, int hi; } foo;或其他丑陋的遗留hack来处理64位数字。任何一个理智的编译器,即使没有C99支持,也有自己的64位类型,你可以用来定义int64_tuint64_t


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接