C99具有一个称为伸缩型数组成员(flexible array member)的新特性。利用这一新特性可以声明最后一个成员是一个具有特殊属性的数组的结构。该数组成员的特殊属性之一是它不立即存在。第二个特殊属性是您可以编写适当的代码使用这个伸缩型数组成员,就像它确实存在并且拥有您需要的任何数目的元素一样。
声明一个伸缩型数组成员的规则:
- 伸缩型数组成员必须是最后一个数组成员。
- 结构中必须至少有一个其他成员。
- 伸缩型数组就像普通数组一样被声明,除了它的方括号是空的。
下面是一个例子:
// flexmemb.c 伸缩型数组成员
#include <stdio.h>
#include <stdlib.h>
struct flex
{
int count;
double average;
double scores[]; // 伸缩型数组成员
};
struct flex * createFlex(size_t n);
void showFlex (const struct flex * p);
int main (void)
{
struct flex *pf1, *pf2;
pf1 = createFlex(5);
showFlex(pf1);
pf2 = createFlex(9);
showFlex(pf2);
free(pf1);
free(pf2);
return 0;
}
struct flex * createFlex(size_t n)
{
struct flex *pf;
int i;
double tot = 0;
pf = malloc(sizeof(struct flex) + n * sizeof(double));
pf->count = n;
for (i = 0; i < n; i++)
{
pf->scores[i] = 20.0 - i / 2.0;
tot += pf->scores[i];
}
pf->average = tot / n;
return pf;
}
void showFlex (const struct flex * p)
{
int i;
printf("Scores: ");
for (i = 0; i < p->count; i++)
printf("%g ", p->scores[i]);
printf("\nAverage: %g\n", p->average);
}
下面是输出:
Scores: 20 19.5 19 18.5 18
Average: 19
Average: 18
针对结构体flex
struct flex
{
int count;
double average;
double scores[]; // 伸缩型数组成员
};
直接求sizeof(struct flex)时得到的是由除了伸缩型数组成员外的其他普通成员构成的大小(注意:可能会有地址对齐使结果不严格为个成员长度之和),即scores初始时不占用内存空间使用struct flex,所以由struct flex直接产生变量是无意义的。但当给其指针动态分配内存空间时,多余的空间会分配给scores数组。所以,如果想要数组大小为n的话,需要对指针分配内存空间如下:
struct flex *pf;
pf = malloc(sizeof(struct flex) + n * sizeof(double));