C语言发展史及标准库梳理
前言
本文主要内容来自网络上公开的资源,来源我贴在了最后。
C语言发展历史
简单的说,C语言是为了开发Unix系统而出现的,C语言最初的开发者是Dennis MacAlistair Ritchie和Kenneth Lane Thompson。
1973年,Unix系统的核心正式采用C语言改写。
C语言发展至今,按时间先后,使用的标准以及主要特性如下。
K&R C
1975年,Brian Wilson Kernighan和Dennis MacAlistair Ritchie合作编写了一本书 《The C Programming Language》。书里介绍的C语言标准,被称为 K&R C。
书中介绍的C语言特性主要包括:
- 标准I/O库
- struct 类型
- long int 类型
- unsigned int 类型
- 把运算符 =+和=-改为+=和-=,以避免编译器在处理时产生混淆
C89(ANSI C)
1989年,C语言被ANSI(美国国家标准协会)标准化,编号为ANSI X3.159-1989,因此这个版本的C语言既被成为C89,也被成为ANSI C。
C89引入的C语言特性主要包括:
- void函数
- 函数返回struct或者union类型
- void *数据类型
C90(ISO C)
1990年,ISO(国际标准组织)开始成立工作组,来制定国际标准的C语言规范,ANSI随之接受ISO的标准,并宣布不再发展新的C语言标准。ISO发布标准,在ANSI C的基础上进行了改进,被称之为C90,或者ISO C。
C90对C语言的改进包括:
- 增加了标准库
- 新的预处理命令和特性
- 函数原型允许在函数申明中指明参数类型
- 一些关键字,包括const、volatile与signed
- 宽字符、宽字符串与多字节字符
- 对约定规则、声明和类型检查的许多小改动与澄清
1994年, ISO的WG14工作组,又对1985年颁布的标准(应该是C++标准)做了两处技术修订和一个补充,主要包括:
- 3个标准库头文件iso646.h、wctype.h和wchar.h
- 几个新记号与预定义宏,用于对国际化提供更好的支持
- printf/sprintf函数一系列新的格式代码
- 大量的函数和一些类型与常量,用于多字节字符和宽字节字符
C99
1994年,ISO对C语言的修订和补充,引出了ISO 9899:1999的发表,这一标准又被成为C99。
C99引入的特性包括:
- 增加了对编译器的限制,比如源代码每行要求至少支持到4095字节,变量名函数名的要求至少到63字节(extern要求支持到31字节)
-
增强了预处理功能,包括
- 宏支持可变参数,即#define Macro(...) VA_ARGS
- 使用宏的时候,允许省略参数,被省略的参数将被扩展成空串
- 支持//开头的单行注释
- 增加了新关键字restrict, inline, _Complex, _Imaginary, _Bool。支持long long, long double _Complex, float _Complex等类型
-
支持不定长的数组,即数组长度可以在运行时决定。但是,考虑到效率和实现,不定长数组不能在全局,或者struct,union中使用
-
变量声明不必放在语句块的开头,for语句提倡写成for(int i = 0; i < 100; ++i)的形式,即i只在for语句块内部有效
-
允许采用(type_name){xx,xx,xx}类似于C++的构造函数的形式构造匿名的结构体
-
初始化结构时,允许对特定的元素赋值,形式为
struct test {
int a[3], b;
} foo[] = {
[0].a = {1},
[1].a = {2}
};
struct test {
int a, b, c, d;
}foo = {
.a = 1,
.c = 3, 4,
.b = 5
};
-
格式化字符串中,利用\u支持unicode的字符
-
支持16进制的浮点数的描述
-
printf/scanf的格式化增加了对long long int类型的支持
-
浮点数的内部数据描述支持了新标准,可以使用 #pragma编译器指令指定
-
除了已有的__line__ file__以外,增加了 __func 获取当前函数名
-
允许编译器化简非常数的表达式
-
修改了 /% 处理负数时的定义,这样可以给出明确的结果。在C89中 -22 / 7 = -3, -22 % 7 = -1, 或者 -22 / 7 = -4, -22 % 7 = 6。C99中明确为-22 / 7 = -3, -22 % 7 = -1,结果是确定的。
-
取消了函数返回值默认为int的规定
-
允许在struct的最后定义的数组不指定其长度(变长数组)
-
const const int i 将被当作 const int i 处理
-
增加和修改了一些标准头文件,详情见下文对标准头文件的汇总
-
输入输出对宽字符以及长整数等做了相应的支持
C11
2011年12月8日,ISO正式发布了新的C语言标准C11,该标准早期被称为C1X,官方名为ISO/IEC 9899:2011。
C11提高了对C++的兼容性,部分增加的特性包括:
-
泛型宏
-
多线程
-
带边界检查的函数
-
匿名结构
C18
2018年6月,ISO发布了C18,官方名称为ISO/IEC 9899:2018。
相比于C11,C18未引入新的语言特性,仅对C11进行了补充和修正。
C语言标准库
名称 | 用途 | 最早引入标准 |
---|---|---|
条件编译宏 | C89 | |
复数运算 | C99 | |
字符类型判断 | C89 | |
涉及错误报告的宏 | C89 | |
浮点数运算环境相关 | C99 | |
float类型的限制 | C89 | |
int类型的格式转换 | C99 | |
可选的运算符拼写方式 | C95 | |
基础类型大小 | C89 | |
本地化工具 | C89 | |
通用的数学函数 | C89 | |
非本地跳转 | C89 | |
信号处理相关 | C89 | |
alignas和alignof 转换宏 | C11 | |
可变变量声明相关 | C89 | |
原子操作相关 | C11 | |
boolean类型相关 | C99 | |
通用的宏定义 | C89 | |
固定长度的int类型 | C99 | |
输入输出 | C89 | |
通用的工具:内存操作,程序工具,字符串转换,随机数 | C89 | |
noreturn 宏相关 | C11 | |
字符串处理 | C89 | |
泛类型的数学宏相关 | C99 | |
线程库 | C11 | |
时间/日期 工具 | C89 | |
UTF-16 和 UTF-32 字符工具 | C11 | |
拓展的多字节和宽字符工具 | C95 | |
区分宽字符类型的函数 | C95 |