在C99标准以前:可以给函数传递数组,但是没有所谓的数组常量可以来传递。C99新增了复合文字。文字是非符号常量。例如:5是int类型的文字;82.3是float类型的文字等等。C99标准委员会认为:如果又能够表示数组和结构内容的复合文字,那么在编写程序的时候要方便的多。
对于数组来说,复合文字看起来像在数组的初始化列表前加上圆括号括起来的类型名。例如,下面是普通数组的声明方式:
int diva[2] = {10,20};
下面是一个复合文字,创建了一个包含两个int值的无名称数组:
(int[2])(10,20);
注意:类型名就是前面声明中去掉diva后剩下的部分。
正如初始化一个命名数组时可以省略数组大小一样,复合文字也可以,如:
(int []){1,2,3};
由于这些复合文字没有名称,因此不可能在一个语句中创建它们,然后在另一个语句中使用它们。而是必须在创建的同时使用某种方法来使用它们,一种方法是使用指针保存它们的位置,比如:
int* ptr;
ptr = (int [2]){3,4};
于是*ptr就是3,ptr[1]是4.
另外,复合文字也可以也可以作为实际参数被传递到带有类型与之匹配的形式参数的函数中:
int sum(int ar[],int n);
...
int totle;
totle = sum((int [3]{1,2,3}),3);这非常方便,使我想起了c++中pair容器中的一个pair方法,也像python语言中的lambda,一次性的使用特性。
结构体也是一样的,比如:
int add(struct xy instance)
{
return instance.x+instance.y;
}
可以这样调用:
int sum = add((struct xy){1,2});
第二个很让人欣喜的特性是伸缩型数组,它用于结构体中。这个特性可以声明最后一个成员是一个具有特殊属性的数组。该特使属性有两点,1.这个数组不存在,至少不是立即存在的。2.我们可以编写代码适当的使用该数组成员,就像它确实存在而且拥有你需要的任何数目的元素一样。听起来很奇怪,我们看一些例子.
首先看看声明这么一个结构体的规则:
1.伸缩型数组成员必须是最后一个数组成员
2.结构中必须至少有一个其他成员
3.伸缩型数组就像普通数组一样被声明,除了他的方括号是空的
比如:
struct flex
{
int count;
double average;
double score[];
};
如果声明了一个struct xy的结构体,你不能使用score做任何事情,因为没有为他分配内存空间。实际上,C99的意图不是让你struct xy类型的变量,而是希望你声明一个指向这个结构体类型的指针,然后用malloc来分配合适的内存空间。例如,假设想要用score表示含有5个double型数值的数组,那么要这样做:
struct flex ptr;
ptr = malloc(sizeof(struct flex) + 5*sizeof(double));现在我们有了足够的内存,以存储count,average和5个double型数值的数组了。可以使用ptr来访问他们:
ptr->count = 5;
ptr->score[2] = 12.3;
你可以在你任何时候修改这个结构体的占用空间的大小。
这正是让人高兴~~