[C.C++] C语言的五套标准:C89、C99、C11、C17和C23(新手必看)

6330 0
Honkers 2025-5-24 11:48:22 来自手机 | 显示全部楼层 |阅读模式

作为一门经典的编程语言,C语言标准随着时间不断演进,以适应新的编程需求和技术发展。

本文将详细介绍 C语言的五套标准:C89、C99、C11、C17 和 C23。我们将从每套标准的背景、主要特性入手,逐步深入,帮助你理解它们之间的差异以及对编程实践的影响。

C89:奠定基础的第一个标准

C89,也称为 ANSI C,是 C语言的第一个正式标准,由美国国家标准协会(ANSI)于 1989 年发布,后在 1990 年被国际标准化组织(ISO)采纳为 ISO/IEC 9899:1990,因此有时也叫 C90。

C89 标准的出现结束了C语言“各自为政”的局面,统一了语法和语义,为开发者提供了一个可靠的参考。

C89 的核心目标是规范已有实现,而不是引入大量新特性。它定义了 C语言的基本语法,比如变量声明、函数定义、指针操作等。以下是 C89 的一些关键特性:

  • 函数原型:C89 要求函数声明时必须指定参数类型,例如 int add(int a, int b);,而不是老式的 int add();。这提高了代码的安全性和可读性。
  • 标准库:C89 定义了标准库的基本内容,比如  和 ,为输入输出、内存管理等提供了统一接口。
  • 单行注释不可用:C89 只支持 /* */ 形式的注释,单行注释 // 尚未引入。

让我们来看一个简单的 C89 程序示例:

  1. #include <stdio.h>
  2. int main(void) {
  3. int a = 5, b = 3;
  4. printf("Sum = %d\n", a + b);
  5. return 0;
  6. }
复制代码

输出结果:

  1. Sum = 8
复制代码

C89 是许多后续标准的基础,尽管现在看来功能有限,但在当时它为 C语言的普及奠定了坚实基础。

C99:功能扩展的重要一步

C99 是 1999 年发布的标准(ISO/IEC 9899:1999),引入了许多现代化特性,使 C语言更灵活、更强大。

相比 C89,C99 的改进主要集中在提高编程效率和支持新的硬件特性上。以下是 C99 的主要亮点:

  • 变长数组(VLA):允许在运行时动态指定数组大小。例如:
  1. int n = 10;
  2. int arr[n]; // 合法
复制代码
  • 单行注释:引入了 //,与传统的 /* */ 并存,方便开发者快速注释。
  • 新的数据类型:增加了 long long int(至少 64 位)和 _Bool(布尔类型,需要包含  使用 bool、true、false)。
  • 内联函数:使用 inline 关键字提示编译器内联优化,提升性能。
  • 灵活的变量声明:不再要求所有变量声明都在代码块开头,可以在需要时声明,例如在 for 循环中直接定义变量。

下面是一个展示 C99 特性的例子:

  1. #include <stdio.h>
  2. #include <stdbool.h>
  3. inline int square(int x) {
  4. return x * x;
  5. }
  6. int main(void) {
  7. int n = 5;
  8. int arr[n]; // 变长数组
  9. for (int i = 0; i < n; i++) { // 循环中声明变量
  10. arr[i] = i;
  11. printf("%d ", square(arr[i]));
  12. }
  13. bool flag = true;
  14. printf("\nFlag is %d\n", flag);
  15. return 0;
  16. }
复制代码

输出结果:

  1. 0 1 4 9 16
  2. Flag is 1
复制代码

C99 的这些特性让 C语言更贴近现代编程需求,但由于部分编译器支持不完整(如早期的 Microsoft Visual C++),它的普及受到一定限制。

C11:现代化的进一步完善

C11(ISO/IEC 9899:2011)发布于 2011 年,重点在于增强 C语言的安全性、并发支持和国际化。

以下是 C11 的核心特性:

  • 线程支持:引入 ,提供标准化的多线程功能,例如线程创建和互斥锁。
  • 类型泛型宏:通过 _Generic 实现类型选择,增强代码灵活性。
  • 静态断言:使用 _Static_assert 在编译时检查条件,例如确保数据类型大小符合预期。
  • 匿名结构体和联合:允许嵌套定义未命名的结构体或联合,提升代码简洁性。

下面是一个展示 C11 线程和静态断言的例子:

  1. #include <stdio.h>
  2. #include <threads.h>
  3. _Static_assert(sizeof(int) >= 4, "int must be at least 32 bits");
  4. int run(void *arg) {
  5. printf("Thread running\n");
  6. return 0;
  7. }
  8. int main(void) {
  9. thrd_t thread;
  10. thrd_create(&thread, run, NULL);
  11. thrd_join(thread, NULL);
  12. return 0;
  13. }
复制代码

输出结果:

  1. Thread running
复制代码

C11 的线程支持让 C语言能够更好地适应多核处理器时代,尽管这些特性是可选的,部分编译器可能不完全实现。

C17:修复与完善

C17(ISO/IEC 9899:2018)发布于 2018 年,所以它也被称为 C18 标准。

C17 是对 C11 的小幅修正版本,主要修复了 C11 中的缺陷和模糊之处,没有引入显著的新特性,与 C11 的主要区别在于文档澄清和错误修复。

例如,C17 改进了对某些边界情况的定义,但对开发者来说,代码几乎无需调整即可从 C11 迁移到 C17。


由于 C17 的变化较小,这里不再赘述代码示例。它更像是一个“补丁包”,确保标准的稳定性和一致性。

C23:面向未来的新标准

C23(ISO/IEC 9899:2023)是截至 2023 年发布的最新标准,目前仍在完善中。它引入了一些实验性特性,并进一步现代化 C语言。

以下是 C23 的部分亮点(基于草案):

  • 空指针常量:明确 nullptr 作为标准空指针,取代传统的 NULL。
  • 二进制整数常量:支持 0b1010 这样的二进制写法,便于位操作。
  • 属性语法:引入类似 C++ 的 [[attribute]] 语法,用于注解代码,例如 [[nodiscard]] 提示返回值不可忽略。


下面是一个简单的 C23 示例:

  1. #include <stdio.h>
  2. [[nodiscard]] int get_value(void) {
  3. return 42;
  4. }
  5. int main(void) {
  6. int binary = 0b1010; // 二进制 10
  7. printf("Binary value: %d\n", binary);
  8. get_value(); // 可能触发编译器警告
  9. return 0;
  10. }
复制代码

输出结果:

  1. Binary value: 10
复制代码

C23 仍在发展中,未来可能会有更多特性加入。它代表了 C语言对现代编程需求的持续适应。

总结与对比

为了帮助你快速掌握这五套标准的差异,以下表格总结了它们的发布时间和主要特性:

标准发布时间主要特性
C891989/1990函数原型、标准库规范
C991999变长数组、单行注释、long long、灵活变量声明
C112011线程支持、类型泛型、静态断言
C172018C11 的缺陷修复
C232023nullptr、二进制常量、属性语法

通过学习这些标准,你就能理解 C 语言程序在不同编译环境中的运行差异,进而根据项目需求选择合适的编译器选项(例如 -std=c99)。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Honkers

荣誉红客

关注
  • 4014
    主题
  • 36
    粉丝
  • 0
    关注
这家伙很懒,什么都没留下!

中国红客联盟公众号

联系站长QQ:5520533

admin@chnhonker.com
Copyright © 2001-2025 Discuz Team. Powered by Discuz! X3.5 ( 粤ICP备13060014号 )|天天打卡 本站已运行