【vscode和c语言】变长数组、不定长数组、软性数组在定义过程中出现未初始化成功的错误variable “arr1“ may not be initialized

一、问题背景

最近在学习C语言时候发现VLA(variable-length array)这个有趣的概念,也就是变长数组、或者称为不定长数组、软性数组。

以前我们在本科学的谭浩强版本C语言中,明确表示数组在定义时必须用常数或常量表达式来描述数组的长度。

但是VLA就打破了这个限制(在C语言标准C99中引入,但是在C++的编译标准中一直没引入),允许在程序中定义一个根据变量取值变化而变化的数组。

也即下面的代码是合法的。

int n = 3;
int arr[n] = {0 , 1, 2};

但是我发现我编写下面这段简单的程序,执行过程中仍然报错【variable “arr1” may not be initialized】。

#include <stdio.h>

int main()
{
    
    
    int a = 4;
    int arr1[a]={
    
    7, 8, 9};
    int arr2[3] = {
    
    1, 2, 3};
    int i=0;
    // arr1[2] = arr2[2];
    // for(i=0; i<3; i++)
    //     printf("%d\n", i);
    for(i=0; i<3; i++)
        printf("%d\n", arr1[i]);

    return 0;
}

在这里插入图片描述
虽然在console中输出了正确结果,但是我仍然心有余悸,对这个错误很是不爽。
在这里插入图片描述

二、解决办法

C99中对VLA有一些限制:

1、VLA必须是自动存储类型,也即必须在函数中定义,也即必须是那种用完就删的局部变量。

2、VLA不能对数组进行初始化,因为它的长度在运行时才能确定。为什么在运行时才能确定呢?因为变量在运行时才能确定,有些人给变量赋予值得方式是用scanf函数,这就导致必须在代码运行过程中由人类手动输入取值,数组的长度才得以确定。而在C90标准中,数组长度在编译结束后就已经确定了。

虽然我上面就是把数组的初始化放在main函数中进行的,也即符合自动存储类型(符合第一条),但是我在定义的时候同时对数组arr1进行了初始化,所以出错了。

在我更改代码如下所示后,运行完美。

#include <stdio.h>

int main()
{
    
    
    int a = 4;
    int arr1[a];
    arr1[0] = 7;
    arr1[1] = 8;
    arr1[2] = 9;
    int arr2[3] = {
    
    1, 2, 3};
    int i=0;
    // arr1[2] = arr2[2];
    // for(i=0; i<3; i++)
    //     printf("%d\n", i);
    for(i=0; i<3; i++)
        printf("%d\n", arr1[i]);

    return 0;
}

在这里插入图片描述
输出当然更是正常地!
在这里插入图片描述

三、一些小建议

我再细心网上冲浪,发现大多数程序员并不是很认可这个VLA的使用。

大家都是喜欢直接用malloc和free通过指针来定义一个可变长度数组,据说这样更稳定、更兼容(不用C99也可以),而且不容易出错。

在使用VLA的时候,有些人发现如果初始化过程中将0赋值进去,可能会出现数据错乱。
在这里插入图片描述

因此我觉得最好的解决办法就是不用变量来描述数组长度,就可以彻底避免这个BUG的发生。

毕竟,C++的很多标准(C++90 C++99 C++11)压根就不包括这个特性,而且C++中有更好的工具(vector和array,相对VLA来说是货真价实的随时随地变长数组)来定义类似变长数组这种数据。

猜你喜欢

转载自blog.csdn.net/PSpiritV/article/details/130022576
今日推荐