哪个版本的C更适合学生学习——C89/90还是C99?
在下个月开始系统编程之前,我正在考虑学习 C 基础知识和语法。在阅读时,我遇到了 C89/99 标准。根据维基百科,
C99引入了几个新特性, 包括内联函数,几个 新数据类型(包括 long long int 和一个复杂类型来表示 复数),可变长度 数组,支持可变参数宏 (可变数量的宏)和支持 对于以以下内容开头的单行注释 //,如 BCPL 或 C++ 中一样。其中许多 已经实施为 多个 C 编译器中的扩展。
C99 大部分是落后的 与C90兼容,但更严格 在某些方面;特别是,一个 缺少类型的声明 说明符不再有 int 隐含地假设。标准宏 STDC_VERSION 定义为值 199901L 以指示 C99 支持 可用。 GCC、Sun Studio 和 其他编译器现在支持许多或 C99 的所有新功能。
我借了一份 K&R,第 2 版,它使用 C89 标准。对于学生来说,使用 C89 是否会使 K&R 涵盖的某些科目失效?如果是,我应该注意什么?
I'm looking into learning C basics and syntax before beginning Systems Programming next month. When doing some reading, I came across the C89/99 standards. According to Wikipedia,
C99 introduced several new features,
including inline functions, several
new data types (including long long
int and a complex type to represent
complex numbers), variable-length
arrays, support for variadic macros
(macros of variable arity) and support
for one-line comments beginning with
//, as in BCPL or C++. Many of these
had already been implemented as
extensions in several C compilers.C99 is for the most part backward
compatible with C90, but is stricter
in some ways; in particular, a
declaration that lacks a type
specifier no longer has int
implicitly assumed. A standard macro
STDC_VERSION is defined with value 199901L to indicate that C99 support
is available. GCC, Sun Studio and
other compilers now support many or
all of the new features of C99.
I borrowed a copy of K&R, 2nd Edition, and it uses the C89 standard. For a student, does the use of C89 invalidate some subjects covered in K&R, and if so, what should I look out for?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
没有理由学习 C89 或 C90 而不是 C99——它实际上已经被取代了。找到 C99 编译器很容易,没有任何理由去学习早期的标准。
这并不意味着您的教授不会强迫您学习 C89。从这里张贴的各种标记为家庭作业的问题中,我感觉到自 C89 以来,很多很多 C(不幸的是,C++)课程都没有继续进行。
从初学者的角度来看,您很可能不会真正注意到其中的差异 - 有大量 C 内容需要涵盖 C99 和 C89/90。
There is no reason to learn C89 or C90 over C99- it's been very literally superseded. It's easy to find C99 compilers and there's no reason whatsoever to learn an earlier standard.
This doesn't mean that your professor won't force C89 upon you. From the various questions posted here marked homework, I get the feeling that many, many C (and, unfortunately, C++) courses haven't moved on since C89.
From the perspective of a starting student, the chances are that you won't really notice the difference- there's plenty of C that's both C99 and C89/90 to be covered.
使用C99标准,它更新并且具有更多功能。特别有用的可能是
中的bool
类型和int32_t
等类型系列;后者可以防止许多依赖于具有一定大小的 int 的不可移植代码。 AFAIK,它不会使 K&R 无效,尽管现在一些示例程序可能会以稍微不同的风格编写。请注意,某些编译器仍然无法正确支持 C99。我相信 GCC 仍然需要使用
-std=c99
标志来启用它;许多 Unix/Linux 系统都有一个c99
命令来包装 GCC 并启用 C99。许多大学教授也是如此。我在大一时交出了一个使用
bool
的程序,这让我大吃一惊。他从来没有听说过 C 语言中的这种类型:)Use the C99 standard, it's newer and has more features. Particularly useful may be the
bool
type in<stdbool.h>
and theint32_t
etc. family of types; the latter prevents a lot of unportable code that relies onint
s having a certain size. AFAIK, it doesn't invalidate K&R, though some example programs may be written in a slightly different style now.Note that some compilers still don't support C99 properly. I believe that GCC still requires the use of a
-std=c99
flag to enable it; many Unix/Linux systems have ac99
command that wraps GCC and enables C99.The same goes for many university professors. I surprised mine by handing in a program that used
bool
in my freshman year. He'd never heard of that type in C :)虽然我基本上同意其他人的观点,但值得注意的是,《K&R》是一本好书,值得从中学习 C,然后在阅读 C99 标准时更新您的知识。
While I generally agree with the others, it is worth noting that K&R is such a good book that it might be worth learning C from it and then updating your knowledge as you read about the C99 standard.
如果您处于学生水平,您可能甚至不会注意到其中的差异。
If you are at student level you probably won't even notice the differences.
是的,这有点奇怪,你可以得到一个响亮的共识,即 K&R 是一本很棒的 C 书,并且还得到一个响亮的共识,即 C99 是 C 的正确/当前/最佳版本。这两个立场是不兼容的 - 即使 K& ;R 是学习“C 意思是 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 编译器会在您尝试使用它们时告诉您。
Yes, it's a bit odd that you can get a loud consensus that K&R is a great C book, and also a loud consensus that C99 is the correct/current/best version of C. The two positions are incompatible - even if K&R is the best book available to learn "C meaning C99", that just implies the rest are rubbish, or are also hopelessly outdated.
I would advise learning and using C99, but keeping an eye to C89 as you do so. If you use a compiler that has both C89 and C99 compliant modes, then you can write a few bits of C89 just to get an idea of the differences. Then if you ever need to write some code intended to be portable to places that C99 doesn't go, you'll know what to do. If you never have to write any such code, then you've wasted perhaps a day.
Writing C89 properly is actually surprisingly difficult, because getting hold of a copy of the C89 standard is difficult. So, C99 if you can, C89 if for some odd reason you have to, and have some awareness what the difference is. Maybe use K&R to cover the very basics, but get a look at some idiomatic C99 as soon as possible.
As for specific issues to be aware of when reading K&R: there's a list of major changes in the foreword of the standard (http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf), although the details aren't laid out there. A lot of them are new features added to C99, so it's not that K&R is wrong, it just may not always use the best tools for a given job. Some of them are quite fiddly things where you should probably consult the standard if you need the details anyway. The rest are things removed from C89, that usually a C99 compiler will tell you about as and when you try to use them.
作为一名学生,这对你影响不大。但如果可能的话,你应该找到一本涵盖 C99 的新 C 书
As a student, that doesn't influence you so much. But if possible, you should find a new C book which covers C99
术语“C89”描述了两种截然不同的语言:
程序员在 1989 年认为委员会在标准不明确的地方描述的语言,并且支持先前存在的实现中常见的功能。
委员会此后决定要描述的语言,这排除了与现有功能的兼容性
窗口。
C99“澄清”了标准中不明确的部分,表示它们的意思是
以一种会破坏实质性的方式解释该标准
现有代码的一小部分,并且无法执行许多任务
其效率与 1989 年之前使用 C 语言执行时一样高效。
对于许多应用程序来说,正确的编程语言是标准前的 C、C89、C99 和 C11 的超集。然而,重要的是,任何使用该语言进行编程的人都必须清楚,他们使用的是该语言,而不是一个更注重速度而不是可靠性的缩小子集。
The term "C89" describes two very different languages:
The language that programmers in 1989 thought the Committee was describing in places where the Standard was ambiguous, and which supported features that were common in pre-existing implementations.
The language that the Committee has since decided that it wanted to have described, which threw compatibility with existing functionality out the
window.
C99 "clarifies" ambiguous parts of the standard by saying that they meant
to have the Standard interpreted in a way that would have broken a substantial
fraction of existing code and made it impossible to perform many tasks as
efficiently as they had been performed in C before 1989.
The right language to program in, for many applications, would be the superset of pre-Standard C, C89, C99, and C11. It's important, however, that anyone programming in that language be clear that they're using that language rather than a shrinking subset which favors speed over reliability.
虽然我认为了解哪些功能是最新的并且不太可能被晦涩的(或故意破坏的,如 MSVC)编译器支持是有益的,但有一些 C99 功能您绝对应该使用:
snprintf
:这是 C 语言中安全、干净的字符串汇编的最终函数。如果您的编译器缺少它,您可以替换整个printf
子系统(这可能是一个好主意,因为大多数实现都使用缺少snprintf
也充满了printf
行为中的(通常是故意的)错误),或包装tmpfile
/fprintf
/fread
/fclose
.stdint.h
:如果需要固定大小类型(16/32/64 位),请使用标准名称int16_t
、uint16_t、
int32_t
等。不要发明自己的,并且绝对不要使用特定于系统的,例如INT64
或u32
。它只会让你的代码变得丑陋并且难以集成和重用。如果您的编译器缺少stdint.h
,只需添加您自己的编译器,根据适合您的平台的类型来定义类型。特别是
uint64_t
,代替int foo[2];
或struct { int lo, int hi; } foo;
或其他可怕的遗留黑客来处理 64 位数字。即使没有 C99 支持,任何正常的编译器都有自己的 64 位类型,您可以使用它来定义int64_t
和uint64_t
。While I think it's beneficial to know which features are more recent and less likely to be supported by obscure (or intentionally-broken, like MSVC) compilers, there are a few C99 features that you should absolutely use:
snprintf
: This is the definitive function for safe and clean string assembly in C. If your compiler is missing it, you can either replace the wholeprintf
subsystem (probably a good idea since most implementations with missingsnprintf
are also full of (often intentional) bugs inprintf
behavior), or wraptmpfile
/fprintf
/fread
/fclose
.stdint.h
: If you need fixed-size types (16/32/64-bit), use the standard namesint16_t
,uint16_t
,int32_t
, etc. Do not invent your own, and absolutely don't use system-specific ones likeINT64
oru32
. It just makes your code ugly and hard to integrate and reuse. If your compiler is missingstdint.h
, just drop in your own to define the types in terms of the correct-for-your-platform types.Specifically
uint64_t
, in place ofint foo[2];
orstruct { int lo, int hi; } foo;
or other hideous legacy hacks to work with 64-bit numbers. Any sane compiler even without C99 support has its own 64-bit types you can use to defineint64_t
anduint64_t
.