一、C 语言普通静态数组

定义语法:

int arr1[10];        
int arr2[] = {1,2,3}; 		//自动推导长度为3

普通静态数组特性:

  1. 数组大小必须是常量 (C89标准强制)
  2. 一旦定义,长度固定,不能扩容、不能缩小
  3. 内存:栈内存(局部数组),分配在栈上
  4. 数组名本质是首元素地址,不能直接赋值
  5. 缺点:无法运行时灵活改变容量,栈空间有限,大数组容易栈溢出
// C89 错误写法
int n;
scanf("%d", &n);
int a[n]; // C89不支持!

二、C99:VLA 变长数组(Variable Length Array,俗称不定长数组)

定义语法:

#include <stdio.h>
int main()
{
    int n;
    scanf("%d", &n);
    int arr[n]; // VLA:运行时n确定数组长度
    for(int i = 0; i < n; i++)
        arr[i] = i;
    return 0;
}

不定长数组特性:

  1. 仅 C99 标准支持,MSVC(微软编译器)不支持 VLA;GCC 支持
  2. 长度只能初始化时确定,不能中途扩容
  3. 依然在栈上分配内存!如果 n 很大,直接栈溢出崩溃
int n=5;
int a[n];
n=10;
// a数组大小依旧是5,不会变化!无法动态扩容
  1. 不能初始化列表赋值不定长数组不能初始化赋值

  2. 作用域结束自动销毁,不需要手动 free

误区:VLA ≠ 动态数组!它只是运行时确定尺寸的定长数组,不可扩容


三、C++ std::vector

定义语法:

#include <vector>
using namespace std;

int main()
{
    vector<int> vec;      // 空动态数组
    vector<int> vec2(10); // 初始10个元素
    vec.push_back(1);     // 自动尾部扩容
    vec.resize(20);
    return 0;
}

vector 特性:

  1. 支持自动扩容,不需要程序员手动管理内存
  2. 自带接口:push_back、pop_back、size()、capacity()
  3. 底层内存在堆上,封装了 malloc/realloc/free
  4. 对象生命周期结束自动释放内存
  5. 不是数组!是封装好的类,内部持有一块连续堆内存

四、三者横向对比

对比维度C静态数组C不定长数组VLAC++ vector
内存位置栈上栈上堆上
长度限制编译期固定运行时确定、不可扩容运行时自动扩容
内存释放栈自动回收栈自动回收对象销毁自动释放堆内存

五、总结

  1. C 静态数组 int a[5]

大小必须是编译常量,支持大括号初始化;存放栈中,长度固定,不能扩容,C89/C99 通用。

  1. C99 VLA 变长数组 int a[n]

运行时确定数组长度,GCC 支持、VS 不支持;存储在栈,定义后尺寸永久不变,禁止int
a[n]={…}初始化;不是真正动态数组,大数据容易栈溢出,工程不推荐。

  1. C++ vector

C++ 独有,底层堆内存;可以自动扩容,提供丰富成员函数;生命周期结束自动释放内存,是标准的动态数组容器,C 语言没有 vector。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐