新C
C99 是 ANSI 和 ISO 标准化组织批准的 C 标准。 它对 C 语言进行了大量更改。 这些变化是 C 和 C++ 之间兄弟竞争的结果。 C 的初始版本以 Kernighan 和 Ritchie 命名。 经典 C 是具有结构分配、枚举和 void 的 K&R C。 C89 或 ANSI C 受到带有类的 C 的一些影响。 为了 example, C89 采用了与 C with Classes 提供的类似形式的函数原型。 与 C89 相比,C99 最显着的变化是支持多种新特性。
以下是 C99 功能的简要列表:
- 布尔数据类型
- 增加标识符大小限制
- C++ 样式/行注释
- 内联函数
- 受限指针
- 变量声明
- 可变长度数组
- 新长长型
具体标准
使用以下命令应用 gcc 的新 C 标准。
$gcc -Wall -std=c99 filename.c
让我们考虑以下名为 bool.c 的程序:
/*bool.c */ #include <stdio.h> #include <stdbool.h> int main(int argc, char *argv[]) { bool b = true; if(b) printf("It is a true Boolean data type supported only in C99n"); else printf("Boolean data type is not supported in C99n"); return 0; } $ gcc -Wall -std=c99 bool.c $ ./a.out It is a true Boolean data type supported only in C99
将 C99 程序与外部库链接
C 标准库由 C 程序使用的头文件和库例程的集合组成。 外部库通常以扩展名 .a 存储,称为静态库。 例如,C 数学库通常存储在 Linux 上的文件 /usr/lib/libm.a 中。 数学库中函数的原型声明在头文件 /usr/include/math.h 中指定。
/*hypotenuse.c*/ #include <stdio.h> #include <math.h> int main(int argc, char *argv[]) { float x,y,h; //C99 program to demonstrate the use of external math library function printf("n Enter the values for x and yn"); scanf("%f %f", &x,&y); h=hypotf(x,y); printf(" The Hypotenuse of x and y is %fn", h); return 0; }
考虑上面的程序 hypotenuse.c。 然后执行以下命令:
$ gcc -Wall -std=c99 hypotenuse.c /usr/lib/libm.so -o hypt $ ./hypt Enter the values for x and y 6.0 8.0 The Hypotenuse of x and y is 10.000000
gcc 提供了一个 -l 选项来在链接库时覆盖长路径。 以下命令说明了此选项:
$ gcc -Wall -std=c99 hypotenuse.c -lm -o hypt $ ./hypt Enter the values for x and y 4.0 8.0 The Hypotenuse of x and y is 8.944272
混合声明
ISO C99 允许声明和代码同时存在于复合语句中。 下面的编程 example 说明了这个特性:
/*mixednewdec.c*/ #include<stdio.h> int main(int argc, char*argv[]) { for(int i=2; i>0 ; --i) { printf("%d", i); int j = i * 2; printf("n %d n", j); } } $ gcc -Wall -std=c99 mixednewdec.c $ ./a.out 2 4 1 2
标识符从声明它的位置到封闭块的末尾都是可见的。
可变长度数组(VLA)
可变长度数组不是动态数组。 相反,每次遇到声明时,它们都会以不同的大小创建。 只有在块范围内的局部数组才能是变量数组。
/*vla.c*/ #include<stdio.h> int main(int argc, char *argv[]) { int j = 10; void func(int); func(j); return 0; } void func(int x) { int arr[x]; for(int i=1; i<=x; i++) { int j=2; arr[i] = j*i; printf("%dn",arr[i]); } }
以前数组大小是固定大小的。 C99 删除了这个约束。 它还使您无需显式地对内存执行 allocate() 和 delete() 操作。 VLA 的输出如下图所示。
$ gcc -Wall -std=c99 vla.c $ ./a.out 2 4 6 8 10 12 14 16 18 20
新长长型
long long 是 64 位宽的整数类型。 这是 C 语言标准中最大的整数类型。 long long 类型被指定为 32 位机器在与 64 位机器交互时提供一种处理 64 位数据的方法。 考虑以下 C 程序 longdt.c:
/*longdt.c*/ #include <stdio.h> int main(int argc, char *argv[]) { long long num1 = 123456789101LL; long int num2 = 12345678; printf("Size of %lld is %u bytesn", num1 ,sizeof(num1)); printf("Size of %ld is %u bytesn", num2 ,sizeof(num2)); return 0; } $ gcc -Wall -std=c99 longdt.c $ ./a.out Size of 123456789101 is 8 bytes Size of 12345678 is 4 bytes
受限指针
C99 允许您在指针声明前加上 restrict 关键字。 因此,指针本身将用于访问它指向的对象。 此功能解决了混叠的不足。 它还有助于代码优化。 为了 example,考虑 string.h 文件中 strcat() 函数的签名:
char *strcat (char* restrict dest, const char * src)
源字符串附加到目标字符串的末尾。 在这里,目标字符串和源字符串只能通过指针 dest 和 src 来引用。 然后编译器可以优化为函数生成的代码。
内联函数
内联函数节省了函数调用的开销。 考虑以下程序 inlinecode.c 来演示 C99 中内联的使用。
/*myheader.h*/ #ifndef MYHEADER_H #define MYHEADER_H inline int min(int a, int b) { return a < b ? a : b; } #endif /*inlinecode.c*/ #include <stdio.h> #include "myheader.h" extern int min(int,int); int main(int argc, char *argv[]) { int a =10, b=20; int min_value = min(10,20); printf(" The minimum of a and b is %dn", min_value); return 0; } $ gcc -Wall -std = c99 inlinecode.c $ ./a.out The minimum of a and b is 10
结论
C99 在 ANSI C 的演进中领先一步。它结合了优雅的特性,如单行注释、布尔数据类型和更大的数据类型。 C99 还通过限制指针使用来支持代码优化并支持内联函数。 现在,程序员可以利用这些新功能并进一步优化他们的代码以提高编程效率。