C++数组有哪些初始化方式?为什么变长数组用{0}初始化报错?
报错原因说明
你代码中用到的int dp[n+1]本身不属于标准C语法,这是C语言的*变长数组(VLA)*特性,仅为GCC等部分编译器对C做的非标准扩展,标准C++要求数组长度必须是编译期可确定的常量表达式,而你的n是函数入参,只有运行时才能确定具体值。
而变长数组的核心特性是长度在运行时才能确定,={0}属于聚合初始化语法,要求初始化列表的长度在编译期就能匹配数组长度,二者特性冲突,因此编译器直接抛出variable sized array cannot be initialized错误。
C++数组常见初始化方式
定长数组(长度为编译期常量,符合C++标准)
- 零初始化:
int arr[10] = {0};所有元素自动初始化为0 - 部分元素初始化:
int arr[10] = {1,2,3};前3个元素设为1、2、3,剩余元素自动初始化为0 - 自动推导长度初始化(C++11及以上):
int arr[]{1,2,3,4};编译器自动推导数组长度为4 - 值初始化(C++11及以上):
int arr[10]{};所有元素零初始化,写法更简洁
运行时确定长度的动态数组(符合C++标准)
标准C++中如果需要使用长度在运行时才能确定的数组,优先推荐使用std::vector容器,初始化非常方便:
- 批量初始化指定值:
vector<int> dp(n+1, 0);直接生成n+1个元素,全部初始化为0,无需手动写循环
如果非要使用原生动态数组,可以申请堆内存后初始化: - 动态申请+memset初始化:
int* dp = new int[n+1]; memset(dp, 0, sizeof(int) * (n+1));用完需要手动执行delete[] dp;释放内存,避免泄漏
非标准变长数组(仅限支持VLA扩展的编译器使用)
如果你坚持使用当前编译器支持的变长数组,除了for循环外,也可以用memset直接初始化:memset(dp, 0, sizeof(dp)); 注意memset是按字节赋值,仅适合初始化0值,无法用来初始化其他数值。
代码优化建议
你当前用的变长数组可移植性极差,换用MSVC等不支持VLA扩展的编译器会直接编译失败,建议直接替换为std::vector,修改后代码如下:
class Solution { public: int numSquares(int n) { vector<int> dp(n+1, 0); // 直接初始化所有元素为0 for(int i=1;i<=n;i++){ int t = INT_MAX; for(int j=1;j<=(int)sqrt(i);j++){ t = min(t,dp[i-j*j]); } dp[i] = t+1; } return dp[n]; } };
内容的提问来源于stack exchange,提问作者Deepak Silver
相关产品推荐
相关产品推荐

