C 知识量:16 - 74 - 317
C语言在C99标准中新增了变长数组(VLA),也就是允许使用变量表示数组的维度,例如:
int m = 2; int n = 3; int box[m][n]; //声明变长数组
变长数组有一些限制,比如:变长数组必须是自动存储类别,也就是说无论在函数中声明还是作为函数形参声明,都不能使用static或extern存储类别说明符,而且不能在声明中初始化它们。
需要注意:
变长数组的“变”指的是在创建数组时,可以使用变量来指定数组的维度,而不是指可以修改已创建的数组的大小。
在C11标准中,变长数组是一个可选特性,不是必须强制实现的特性,因此,不是所有编译器都支持变长数组。
在声明一个将变长数组作为形参的函数时,需要首先声明变长数组的两个维度,然后是变长数组本身,顺序不能错。例如:
int sum_vla(int rows, int cols, int box[rows][cols]);//正确的声明 int sum_vla(int box[rows][cols], int rows, int cols);//错误的声明
可以省略原型中的形参名,但是必须用星号(*)来代替省略的维度:
int sum_vla(int, int, int box[*][*]);
下面利用变长数组,实现一个能够计算任意大小的二维int数组元素之和的函数:
#include <stdio.h> //声明计算任意大小的二维int数组元素之和的函数 int sum_vla(int rows, int cols, int box[rows][cols]); int main(void) { int rows = 3; int cols = 4; int box[rows][cols]; //声明二维变长数组 //赋值变长数组 for (int i = 0; i < rows; i++) for (int j = 0; j < cols; j++) box[i][j] = i + j; //打印变长数组 for (int i = 0; i < rows; i++) for (int j = 0; j < cols; j++) printf("row:%d col:%d value:%d\n", i, j, box[i][j]); //调用函数计算数组元素的和 printf("Sum of all elements = %d\n", sum_vla(rows, cols, box)); system("pause"); return 0; } //定义计算任意大小的二维int数组元素之和的函数 int sum_vla(int rows, int cols, int box[rows][cols]) { int r; int c; int tot = 0; for (r = 0; r < rows; r++) for (c = 0; c < cols; c++) tot += box[r][c]; return tot; }
运行结果为:
row:0 col:0 value:0 row:0 col:1 value:1 row:0 col:2 value:2 row:0 col:3 value:3 row:1 col:0 value:1 row:1 col:1 value:2 row:1 col:2 value:3 row:1 col:3 value:4 row:2 col:0 value:2 row:2 col:1 value:3 row:2 col:2 value:4 row:2 col:3 value:5 Sum of all elements = 30
变长数组允许动态内存分配,可以在程序运行时指定数组的大小。而普通的数组都是静态内存分配,在编译时就确定数组的大小。
C语言的C99标准增加了复合字面量。字面量是除符号常量以外的常量。例如:100是int类型的字面量,3.14是double类型的字面量,'A'是char类型的字面量,"world"是字符串字面量等等。对于数组,复合字面量类似数组初始化列表,前面是用括号括起来的类型名,以下是一个示例:
int box[2] = {100, 200}; //普通的数组 (int [2]){100, 200}; //复合字面量
去掉数组名,留下的int[2]就是复合字面量的类型名。跟数组一样,在初始化时复合字面量也可以省略大小,编译器会自动计算数组当前的元素个数:
(int []){100, 200};
由于复合字面量是匿名的,所以不能先创建再使用,必须在创建的同时使用它,例如:
int * p; p = (int [2]){100, 200};
以上代码中,复合字面量的类型名代表着首元素的地址,因此,可以赋值给指针p。
除此之外,还可以将复合字面量作为实参直接传递给函数,例如:
int sum(int b[]); int tot; tot = sum((int [2]){100, 200});
在函数参数中使用复合字面量的好处就是,在信息传入函数前不必先创建数组。复合字面量是提供只临时需要的值的一种手段,它具有块作用域,也就是说一旦离开定义复合字面量的块,程序将无法保证该字面量是否存在。注意:复合字面量的定义在最内层花括号中。
Copyright © 2017-Now pnotes.cn. All Rights Reserved.
编程学习笔记 保留所有权利
MARK:3.0.0.20240214.P35
From 2017.2.6