前言:
最近在复习C,发现了一些新东西,例如:变长数组,复合文字,指针的兼容性等。今天先简单谈一下复合文字。
正文:
假如需要向带有一个int参量的函数传递一个值,您可以传递一个int变量,也可以传递一个int常量,比如5。在C99标准以前:可以给函数传递数组,或者其他自定义的结构等,但是没有所谓的数组(结构)常量可以来传递。C99新增了复合文字(compound literal)。文字是非符号常量。例如:5是int类型的文字;82.3是float类型的文字等等。C99标准委员会认为:如果又能够表示数组和结构内容的复合文字,那么在编写程序的时候要方便的多。
1.对于数组来说,复合文字看起来像是在数组的初始化列表前面加上用圆括号括起来的类型名。
int diva[2]={10,20};//普通数组 (int [2]){10,20};//一个复合文字
注意:类型名就是前面声明中去掉diva后剩余的部分,即int[2]。
2. 正如初始化一个命名数组时可以省略数组大小一样,初始化一个复合文字时可以省略数组大小,编译器会自动计算元素的数目:
(int []){50,20,90};//有3个元素的复合文字
3. 由于这些复合文字没有名称,因此不可能在一个语句中创建它们,然后在另一个语句中使用。而是必须在创建它们的同时通过某种方法来使用它们,一种方法是使用指针保存其位置。请看下面的例子:
int* pt1; pt1=(int [2]){10,20};
众所周知,数组名其实就是指向数组首元素的指针,所以此处的pt1就相当于数组名,所以之后可以像使用数组名一样,使用这个指针了。
4. 另外,复合文字也可以做为实际参数被传递给带有类型与之匹配的形式参量的函数:
int sum(int ar[],int n) { int total=0; for(int i=0;i<n;i++) total+=ar[i]; return total; } int tot; tot=sum((int[]{1,2,3,4,5,6}),6);
此处第一个参数是包含6个元素的int型数组,同时也是首元素的地址(同数组名一样)。这种给函数传递信息而不必先创建数组的做法,是复合常量的通常使用方法。
5. 可以把这种技巧用在处理二维数组或多维数组的函数中。例如,下面的代码介绍如何创建一个二维int数组并保存其地址:
int (*pt2)[4];//声明一个数组指针 pt2=(int [2][4]){{1,2,3,-9},{4,5,6,-8}};
6. 在结构中也可以使用复合文字。
int add(struct xy instance) { return instance.x+instance.y; } int sum = add((struct xy){1,2}); //调用
7.对复合文字进行取址操作。
struct point{ double x; double y; }; struct point* instance=&((struct point){2.2,2.3});
8.总结:
(1)当一个类似结构的东西需要临时构造的时候,可以用 (type_name){xx,xx,xx},而type_name就是之前定义的格式,去掉变量名(数组名)即可, 这种使用方法有点像 C++ 的构造函数。
(2)其实,复合文字就相当于一个常量,只不过形式较为复杂而已,所有可以用常量的地方均可以用复合文字,例如,宏定义。
(3)使用复合文字,在想传一个“常量”时,就不必先定义,再传值了,比如传一个常数坐标(struct point{double x;double y;}),这样就不用先定义一个结构变量,再传结构体过去了,代码更加简洁。
(4)值得注意的是,复合文字具有左值语义。