首页 > 编程笔记 > C语言笔记 阅读:87

C语言变长数组(VLA)的用法(非常详细,附带实例)

在 C语言中,变长数组(Variable Length Array,简称 VLA)是一种可以在运行时动态确定大小的数组。

变长数组是 C99 标准引入的新特性,它允许数组的长度不是固定的编译时常量,而是根据程序运行时的变量或表达式来决定。

变长数组的概念

在 C 语言里,传统的数组(如 int arr[10])要求在声明时指定一个固定的长度,这个长度必须是编译时已知的常量。而变长数组打破了这一限制,其大小可以在运行时动态计算,通常由变量或函数参数决定。

变长数组的内存分配仍然是在栈上完成的(与动态分配的堆内存不同),它的核心特点包括:
接下来,我们将从语法开始,逐步讲解变长数组的用法。

变长数组的声明

变长数组的声明与普通数组类似,但长度部分可以用变量或表达式替代。基本语法如下:

数据类型 数组名[表达式];

这里的 表达式 在运行时计算,确定数组的大小。例如:

int n = 5;
int arr[n]; // 变长数组,大小为 n

需要注意的是,n 的值必须在数组声明时已经确定,且不能为负数或零,否则会导致未定义行为。

变长数组的基本用法

让我们通过一个简单示例来看看变长数组的实际应用。假设我们要根据用户输入的大小创建一个数组:

#include <stdio.h>

int main() {
    int n;
    printf("请输入数组大小:");
    scanf("%d", &n);
    int arr[n]; // 变长数组

    // 初始化数组
    for (int i = 0; i < n; i++) {
        arr[i] = i + 1;
    }

    // 打印数组
    printf("数组内容:");
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
    return 0;
}

输出结果(假设输入 5):

请输入数组大小:5
数组内容:1 2 3 4 5 

在这个例子中,arr 的大小由用户输入的 n 决定。程序根据 n 创建了一个变长数组,并对其进行初始化和输出。

变长数组在函数中的使用

变长数组特别适合作为函数的局部变量,尤其在需要动态大小的场景中。

例如,我们可以编写一个函数,根据参数创建变长数组并计算元素之和:

#include <stdio.h>

void sum_array(int size) {
    int arr[size]; // 变长数组
    for (int i = 0; i < size; i++) {
        arr[i] = i * 2;
    }
    int sum = 0;
    for (int i = 0; i < size; i++) {
        sum += arr[i];
    }
    printf("数组元素之和:%d\n", sum);
}

int main() {
    int n;
    printf("请输入数组大小:");
    scanf("%d", &n);
    sum_array(n);
    return 0;
}

输出结果(假设输入 4):

请输入数组大小:4
数组元素之和:12

这里,arr[size] 的长度由函数参数 size 决定,数组元素为 0、2、4、6,总和为 12。

多维变长数组

C99 还支持多维变长数组,常用于动态矩阵等场景。声明时,至少有一个维度可以是运行时表达式。例如:

#include <stdio.h>

void print_matrix(int rows, int cols) {
    int matrix[rows][cols]; // 多维变长数组
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            matrix[i][j] = i + j;
        }
    }
    printf("矩阵内容:\n");
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            printf("%d ", matrix[i][j]);
        }
        printf("\n");
    }
}

int main() {
    print_matrix(3, 4);
    return 0;
}

输出结果:

矩阵内容:
0 1 2 3 
1 2 3 4 
2 3 4 5 

在这个例子中,matrix 是一个 3 行 4 列的变长数组,行数和列数由函数参数动态指定。

变长数组与动态内存分配的对比

变长数组常被拿来与动态内存分配(mallocfree)对比,二者都能实现动态大小的数组,但有显著区别。以下是两者的对比表格:
 

特性 变长数组 动态内存分配
内存位置
生命周期 自动释放(离开作用域) 需手动释放(free
大小限制 受栈空间限制(较小) 受堆空间限制(较大)
语法复杂度 简单 需手动管理

示例(动态内存分配版本):

#include <stdio.h>
#include <stdlib.h>

int main() {
    int n;
    printf("请输入数组大小:");
    scanf("%d", &n);
    int *arr = (int *)malloc(n * sizeof(int));
    for (int i = 0; i < n; i++) {
        arr[i] = i + 1;
    }
    printf("数组内容:");
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
    free(arr);
    return 0;
}

变长数组更简洁,但动态分配更灵活,适合大数组或需要跨作用域使用的情况。

变长数组的优点与局限性

1) 优点

2) 局限性

注意事项


示例(检测栈溢出风险):

#include <stdio.h>

int main() {
    int n = 1000000; // 过大可能溢出
    int arr[n];
    printf("创建了一个大小为 %d 的数组\n", n);
    return 0;
}

这种代码在小型栈环境中可能失败,需谨慎使用。

总结

变长数组是 C99 标准新增的特性,它允许数组的长度不是固定的编译时常量,而是根据程序运行时的变量或表达式来决定,特别适合需要动态大小的局部数组场景。

阅读完本文,相信你已经掌握了 C 语言变长数组的用法。注意,使用变长数组时要注意栈空间限制和兼容性的问题。建议读者学完后多尝试使用变长数组,趁热打铁,彻底掌握它。

相关文章