C99已经存在了10多年,但对它的支持一直很缓慢,因此大多数开发人员都坚持使用C89.即使在今天,当我遇到C代码中的C99功能时,我有时会感到有些惊讶.
现在大多数主要编译器都支持C99(MSVC是一个值得注意的例外,而且一些嵌入式编译器也落后了),我觉得与C合作的开发人员可能应该知道他们可以使用哪些C99功能.一些功能只是之前从未标准化的常见功能(snprintf例如),或者熟悉C++(灵活的变量声明放置或单行//注释),但是一些新功能首先在C99中引入并且是许多程序员都不熟悉.
您在C99中找到了哪些最有用的新功能?
作为参考,C99标准(标记为草案,但据我所知,与更新的标准相同),新功能列表以及GCC C99实施状态.
请回答一个问题; 随时留下多个答案.鼓励展示新功能的简短代码示例.
Jon*_*eid 77
我很习惯打字
for (int i = 0; i < n; ++i) { ... }
Run Code Online (Sandbox Code Playgroud)
在C++中,使用非C99编译器很痛苦,我不得不说
int i;
for (i = 0; i < n; ++i ) { ... }
Run Code Online (Sandbox Code Playgroud)
Bri*_*ell 72
stdint.h,定义int8_t,uint8_t等等.不再需要对整数的宽度进行非可移植的假设.
uint32_t truth = 0xDECAFBAD;
Run Code Online (Sandbox Code Playgroud)
Jon*_*ler 66
我认为新的初始化机制非常重要.
struct { int x, y; } a[10] = { [3] = { .y = 12, .x = 1 } };
Run Code Online (Sandbox Code Playgroud)
好的 - 不是一个引人注目的例子,但符号是准确的.您可以初始化数组的特定元素以及结构的特定成员.
也许更好的例子就是这个 - 虽然我承认它并不是非常引人注目:
enum { Iron = 26, Aluminium = 13, Beryllium = 4, ... };
const char *element_names[] =
{
[Iron] = "Iron",
[Aluminium] = "Aluminium",
[Beryllium] = "Beryllium",
...
};
Run Code Online (Sandbox Code Playgroud)
Meh*_*ari 51
可变长度数组:
int x;
scanf("%d", &x);
int a[x];
for (int i = 0; i < x; ++i)
a[i] = i * i;
for (int i = 0; i < x; ++i)
printf("%d\n", a[i]);
Run Code Online (Sandbox Code Playgroud)
mik*_*csh 41
能够在块的开头以外的位置声明变量.
Chr*_*oph 29
复合文字.逐个成员设置结构是'89;)
您还可以使用它们来获取具有自动存储持续时间的对象的指针,而无需声明不必要的变量,例如
foo(&(int){ 4 });
Run Code Online (Sandbox Code Playgroud)
的内心
int tmp = 4;
foo(&tmp);
Run Code Online (Sandbox Code Playgroud)
Gre*_*osz 29
灵活的阵列成员.
6.7.2.1结构和联合规范
作为一种特殊情况,具有多个命名成员的结构的最后一个元素可能具有不完整的数组类型; 这被称为灵活的数组成员.除了两个例外,忽略了灵活的数组成员.首先,结构的大小应该等于其他相同结构的最后一个元素的偏移量,该结构用一个未指定长度的数组替换灵活的阵列成员.第二,当a
.(或->运算符有一个左操作数,它是一个带有灵活数组成员的结构(指针),右操作数命名该成员,它的行为好像该成员被替换为最长的数组(具有相同的元素类型)使结构大于被访问的对象; 数组的偏移量应保持灵活数组成员的偏移量,即使这与替换数组的偏移量不同.如果此数组没有元素,则其行为就好像它有一个元素,但如果尝试访问该元素或生成一个经过它的指针,则行为未定义.
例:
typedef struct {
int len;
char buf[];
} buffer;
int bufsize = 100;
buffer *b = malloc(sizeof(buffer) + sizeof(int[bufsize]));
Run Code Online (Sandbox Code Playgroud)
Pat*_*ter 25
布尔型.
你现在可以这样做:
bool v = 5;
printf("v=%u\n", v);
Run Code Online (Sandbox Code Playgroud)
将打印
1
Run Code Online (Sandbox Code Playgroud)
Cod*_*ain 18
支持inline功能.
u0b*_*6ae 18
已经提到的复合文字,但这是我引人注目的例子:
struct A *a = malloc(sizeof(*a));
*a = (struct A){0}; /* full zero-initialization */
/* or */
*a = (struct A){.bufsiz=1024, .fd=2}; /* rest are zero-initialized. */
Run Code Online (Sandbox Code Playgroud)
这是一种清晰的方法来初始化数据,即使它在堆上.没有办法忘记零初始化的东西.
Bri*_*ell 15
Unicode转义序列支持:
printf("It's all \u03B5\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03AC to me.\n");
Run Code Online (Sandbox Code Playgroud)
甚至,字面上的Unicode字符:
printf("???\n");
Run Code Online (Sandbox Code Playgroud)
(注意:可能不起作用,具体取决于您的语言环境;对不同编码的便携式支持将需要更多工作)
Ste*_*non 12
十六进制浮点常量(0x1.8p0f)和转换说明符(%a,%A).如果经常处理低级数字细节,这些是对十进制文字和转换的巨大改进.
它们可以避免在为算法指定常量时对舍入的担忧,并且对于调试低级浮点代码非常有用.
| 归档时间: |
|
| 查看次数: |
13128 次 |
| 最近记录: |