标准化之前的一切通常被称为“K&R C”,这是根据著名书籍(第一版和第二版)命名的,其中Dennis Ritchie是C语言的发明者之一。这是1972年至1989年的“C语言”。
第一个C标准于1989年由美国国家标准协会ANSI在美国全国范围内发布。这个版本被称为C89或ANSI-C。从1989年到1990年,这是“C语言”。
在此之后的一年,美国标准被国际接受并由国际标准化组织ISO发布(ISO 9899:1990)。这个版本被称为C90。从技术上讲,它与C89/ANSI-C是相同的标准。从形式上讲,它取代了C89/ANSI-C,使它们过时了。从1990年到1999年,C90是“C语言”。
请注意,自1989年以来,ANSI与C语言无关,除了作为ISO标准的众多实例之一。现在在美国通过INCITS进行,C标准在美国正式称为INCITS/ISO/IEC 9899。就像在欧洲被称为EN/ISO/IEC一样。
仍然谈论“ANSI C”的程序员通常对其含义一无所知。ISO通过标准ISO 9899“拥有”C语言。
1995年发布了一个小的更新,有时被称为“C95”。这不是一个重大修订,而是一个名为ISO/IEC 9899:1990/Amd.1:1995的技术修正案。主要变化是引入了宽字符支持。
1999年,C标准经历了一次重大修订(ISO 9899:1999)。这个版本的标准被称为C99。从1999年到2011年,这是“C语言”。
2011年,C标准再次改变(ISO 9899:2011)。这个版本被称为C11。语言中添加了诸如_Generic
、_Static_assert
和线程支持等各种新功能。这次更新主要关注多核、多处理和表达式排序。从2011年到2017年,这是“C语言”。
2017年,C11进行了修订并解决了各种缺陷报告。这个标准非正式地称为C17或C18。它于2017年完成(并使用__STDC_VERSION__
= 201710L
),但由ISO作为9899:2018发布,因此C17/C18之间存在歧义。它没有引入新功能,只是进行了修正。这是C语言的当前版本。
一个名为“C23”或“C2X”的草案正在委员会进行中,计划于2023年发布(但官僚机构的轮子转动缓慢,请查看ISO的状态)。最新的工作草案N3096可以在这里找到。
它包含了很多像C17/C18那样的小缺陷修复,但也包含了很多重大变化和新功能。这是一个重大版本。
我在这里总结了最有可能影响普通C程序员的变化:C23是什么,我为什么要关心它?
gcc program.c
进行编译,那么你并不是按照C标准进行编译,而是使用了非标准的GNU设置,这可能被称为“GNU C”。例如,整个Linux内核是用非标准的GNU C编写的,而不是标准C。gcc -std=c99 -pedantic-errors
。如果你的GCC版本支持,将c99替换为c17。我必须就 ANSI C 作出回应。尽管ANSI没有做任何相关工作,但编译器仍然按照它构建。例如 PIC XC16 编译器: "该编译器是一款完全符合ANSI规范(ANSI x3.159-1989)所定义的 ANSI C 标准,并在 Kernighan 和 Ritchie 的《C程序设计语言》(第二版)中有所描述的经过验证的编译器……" 并非所有的编程都是针对像个人电脑这样的“大”计算机。 为您的设备编写编译器成本高昂,验证也需要时间和金钱。 ANSI C 在嵌入式/实时设备中仍然活跃且发展。
int i; int test(double *p) { i=1; *p=2.0; return i; }
这样的代码,编译器不需要在写入 *p
后重新加载 i
,以防万一 p
可能持有 i
的地址。这是完全合理的。问题在于现代编译器使用相同的规则来证明对 long*
的写入不会影响 long long
,即使两种类型具有相同的大小和表示形式,并且即使两个结构共享一个公共初始序列,代码也永远不会使用一个类型的指针来读取通过另一个类型写入的CIS成员。 - supercatANSI C:
第一个C语言标准是由名为ANSI的机构在1989年制定,因此被称为c89。
C99:
随着开发者需求的增加,在1999-2000年间C99中添加了进一步的关键字和功能(例如:inline,boolean...添加了浮点运算库函数)
GNU C:
GNU是类Unix操作系统(www.gnu.org),某些GNU项目需要基于ANSI C标准的C编程语言。GNU使用GCC(GNU编译器集合)编译器来编译代码。它具有定义系统调用(如malloc,calloc,exit等)的C库函数。
ANSI C是被其他标准所引用或使用的标准。
这个问题在网络上没有得到充分的搜索,但是您可以看一下以下内容:
-std=c99
,这已经在其他答案中提到。gcc
支持 -std=c89
和 -std=gnu89
和 -std=c99
和 -std=gnu99
(现代版本还支持 -std=c11
和 -std=gnu11
)。区别在于标准 C 的扩展是否自动可用,或者只有当源代码使用适当的宏(例如 -D_XOPEN_SOURCE=700
)促使编译器提供它们时才可用。 - Jonathan Leffler