阅读 宋劲杉 老师的 Linux C 编程一站式学习 后总结 C99 引入的新特性。
声明跟语句顺序
C89 要求所有声明写在所有语句之前,而 C99 允许语句和声明按任意顺序排列,只要每个标识符遵循先声明后使用的原则就行。
初始化和赋值
复合类型
如下例子,C99 中 z1 必须是局部变量才能用另外一个变量 x 的值初始化,如果是全局变量就只能⽤常量表达式来初始化。C89 中不管局部变量还是全局变量都必须常量表达式才能初始化。
double x = 3.0;
struct complex_struct z1 = { x, 4.0, }; /* z1.x=3.0, z1.y=4.0 */
C99引⼊⼀种新的表达式语法Compound Literal可以⽤来赋值,例如
z1 = (struct complex_struct){ 3.0, 4.0}; // 支持
z1 = { 3.0, 4.0}; // 不支持
Designated Initialization
初始化稀疏结构体和稀疏数组很方便,结构体或数组中只有某一个或某几个成员需要初始化,其它成员都用 0 初始化,使用这个语法可以很方便的针对某个成员做初始化 (Memberwise Initialization) 。
struct complex_struct {
double x, y;
} z1, z2;
struct complex_struct z1 = { .y = 4.0}; /* 结构,z1.x=0.0, z1.y=4.0 */
int count[4] = { [2] = 3 }; /* 数组 */
int a[3][2] = { [0][1] = 9, [2][1] = 8 }; /* 多维数组 */
struct complex_struct { /* 嵌套方式 */
double x, y;
} a[4] = { [0].x = 8.8 };
变长数组 (Variable Length Array, VLA)
正常数组类型的长度用一个整数常量表达式来指定。C99 允许在数组长度表达式中使用变量,称为变长数组。只能定义为局部变量而不能是全局变量。
循环
C99规定了⼀种新的 for 循环语法,在控制表达式1的位置可以有变量定义。从C++借鉴的。
for (int i = 0; i < 10; i++) { //i是循环的局部变量,不是函数的局部变量
;
}
关键字
- C99 引入内联函数 (inline function),
inline
告诉编译器函数调用要尽量快,可以当普通函数调用,也可以当做宏展开来实现。 - C99 定义了专门的布尔类型
_Bool
。 restrict
告诉编译器可以放⼼地对这个函数做优化,程序员⾃⼰会保证这些指针所指的内存区间互不重叠。
void *memcpy(void * restrict s1, const void * restrict s2, size_t n); // 不允许优化
杂
- C99 借鉴 C++ 引入单行注释
// comment
。 - C99 引⼊⼀个特殊的标识符
__func__
⽀持这⼀功能。这个标识符应该是⼀个变量名⽽不是宏定义,不属于预处理的范畴,但它的作⽤和__FILE__
、__LINE__
类似。