C语言中有没有见过(int [2]){19,20}或者int (*pt2)[4]的使用方法,字面上可能不好理解,这是C99之后才新增的知识点,名为复合型表述Compound Literals,一旦熟悉使用,便会体会到它简洁而强大的表达。 什么是”复合型表述“? 假设给带int类型的形参函数传递一个值,可以传递int类型的变量,也可以传递int类型常量,但是对于带数组形参的函数则不一样,可以传递数组,但是不支持传递数组常量,由此C99新增了“复合形表述”的用法,“表述(Literals)”是指除符号常量外的常量。 例如10是一种int的类型的表述,10.24是一种double类型的表述,“lixiaoyao”是一种字符串类型的表述等——这些都是关于单个类型常量值的表述。自然而然的,对于数组或者结构体这种内部存在多个成员的数据类型,其关于常量的表述就叫做复合型表述。 关于数组的复合型表述 数组的复合型表述和数组初始化列表差不多,前面使用括号括起来的类型名,例如下面是一个普通的数组声明。 int age[2]=[19,20]; 下面创建了一个和age数组相同的匿名数组,也有两个int类型值。 (int [2]){19,20}; //复合型表述 注意去掉申明中的数组名,留下的int[2]就是复合型表述的类型名。 初始化有数组名的数组可以省略数组的大小,复合型表述也可以省略大小,编译器会自动计算数组当前的元素个数: - C++
- (int []){19,20,21,22,23}//内含5个元素的复合型表述
因为复合型表述是匿名的,所以不能先创建然后再使用它,必须在创建的同时使用它,如下: - C++
- int x;
- // 正确
- x = 100;
- int arr[1];
- // 错误
- arr = {0};
一般需要这样定义使用: - C++
- int *pt1;
- pt1=(int[2]){19,20};
注意,该复合型表述的字面常量与上面创建age数组的表述量完全相同,复合型表述的类型名也代表着首元素的地址,所以可以把它赋给指向int的指针。 作为实际参数 复合型表述作为实际参数传递给带有匹配形式参数的函数。 - C++
- #include <stdio.h>int sum(const int age[],int n);
- int main () {
- int total;
- total =sum((int[]){4,4,4,5,5,5},6);
- return 0;
- }
- int sum(const int age[],int n){
- int i=0;
- for(i=0;i<n;i++){
- printf("age is %d\n",age);
- }
- }
输出结果如下:
应用于二维数组或者多维数组 这种用法还可以应用于二维或者多维数组,例如下面演示了如何创建二维int数组并存储其地址。 - Markdown
- int (*pt2)[4];
- //申明一个指向二维数组的指针,该数组内有2个数组元素
- //每个元素是内含4个int类型值的数组
- pt2 = (int [2][4]) {{1,2,3,4,},{5,6,7,8,}};
对于结构体 假设如下所示声明了struct foo和structure: - C++
- struct foo {int a;
- char b[2];
- } structure;
这是使用复合型表述构造struct foo的示例: - TOML
- structure = ((struct foo) {x + y, 'a', 0});
这等效于以下代码: - C++
- {
- struct foo temp = {x + y, 'a', 0};
- structure = temp;
- }
也可以构造一个数组,如下所述,如果复合型表述的所有元素都是由简单的常量表达式组成,则可以将复合型表述强制转换为指向其第一个元素的指针,并在此类初始化程序中使用, 如下所示: - C++
- char **foo = (char *[]) { "x", "y", "z" };
标量类型和联合类型的复合型表述也被允许,在下面的示例中,变量i初始化为值2,该值是由复合型表述创建的未命名对象递增的结果。
作为GNU扩展,GCC允许通过复合型表述初始化具有静态存储持续时间的对象,如果复合型表述和对象的类型匹配,则如同仅使用括号括起来的列表初始化对象一样处理该对象,复合型表述的元素必须是常量。如果要初始化的对象具有未知大小的数组类型,则该大小由复合型表述的大小确定。 - C++
- static struct foo x = (struct foo) {1, 'a', 'b'};
- static int y[] = (int []) {1, 2, 3};
- static int z[] = (int [3]) {1};
等效于以下内容: - C++
- static struct foo x = {1, 'a', 'b'};
- static int y[] = {1, 2, 3};
- static int z[] = {1, 0, 0};
|