You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++编译报错:expression must have a constant value问题求助

滑动窗口最大值代码的编译错误分析与解决

问题描述

以下是实现滑动窗口最大值的C++代码:

#include <iostream>
#include <deque> 
using namespace std;

void printKMax(int arr[], int n, int k) {
    deque<int>dq;
    int i;
    for (i = 0; i < k; i++) {
        while (dq.back() < arr[i]) {
            dq.pop_back();
            dq.push_back(i);
        }
    }
    for (; i < n; i++) {
        cout << dq.front();
        while (dq.front() <= i - k) {
            dq.pop_front();
        }
        while (dq.back() < arr[i]) {
            dq.pop_back();
            dq.push_back(i);
        }
    }
    cout << dq.front();
}

int main() {

    int t;
    cin >> t;
    while (t > 0) {
        int n, k;
        cin >> n >> k;
        int i;
        int arr[n];
        for (i = 0; i < n; i++)
            cin >> arr[i];
        printKMax(arr, n, k);
        t--;
    }
    return 0;
}

编译时int arr[n];行出现以下错误:

  • expression must have a constant value
  • the value of variable cannot be used as a constant
  • expression did not evaluate to a constant

错误原因

标准C++不支持变长数组(Variable-Length Array, VLA),n是程序运行时通过输入获取的变量,不是编译期能确定的常量,因此不能用来定义数组的大小。部分编译器(如GCC)将变长数组作为非标准扩展支持,但这会导致代码失去可移植性,换用其他编译器(如MSVC)就会触发上述编译错误。

解决方法

方法1:使用std::vector(推荐)

std::vector是标准C++提供的动态数组容器,完全符合标准,且无需手动管理内存。修改步骤:

  1. 添加<vector>头文件;
  2. 将int arr[n];替换为vector<int> arr(n);。

修改后的main函数部分:

#include <iostream>
#include <deque>
#include <vector> // 新增头文件
using namespace std;

// ... printKMax函数不变 ...

int main() {
    int t;
    cin >> t;
    while (t > 0) {
        int n, k;
        cin >> n >> k;
        int i;
        vector<int> arr(n); // 替换变长数组
        for (i = 0; i < n; i++)
            cin >> arr[i];
        printKMax(arr.data(), n, k); // 用data()获取底层数组指针
        cout << endl; // 可选:每次测试用例后换行,输出更清晰
        t--;
    }
    return 0;
}

方法2:动态内存分配(new/delete)

手动申请堆内存,注意使用完后要释放避免内存泄漏:

int main() {
    int t;
    cin >> t;
    while (t > 0) {
        int n, k;
        cin >> n >> k;
        int i;
        int* arr = new int[n]; // 动态分配内存
        for (i = 0; i < n; i++)
            cin >> arr[i];
        printKMax(arr, n, k);
        delete[] arr; // 释放内存
        cout << endl;
        t--;
    }
    return 0;
}

方法3:启用编译器扩展(不推荐)

如果必须使用变长数组,可以在支持该扩展的编译器中开启对应选项(如GCC添加-std=gnu++11或更高版本参数),但此方法会导致代码无法在标准C++编译器中编译,不建议使用。

额外:滑动窗口逻辑错误修正

原printKMax函数存在逻辑错误,即使编译通过也无法得到正确结果,需要修正:

  1. 双端队列存储的是数组索引,比较时应使用索引对应的数组值,而非索引本身;
  2. 操作队列前需判断队列是否为空,避免访问空队列的back()或front()导致未定义行为;
  3. push_back(i)应放在while循环外部,否则每次弹出元素就会立即插入当前索引,逻辑混乱。

修正后的printKMax函数:

void printKMax(int arr[], int n, int k) {
    deque<int> dq;
    int i;
    for (i = 0; i < k; i++) {
        // 移除队列中所有比当前元素小的索引,确保队列头部是窗口最大值的索引
        while (!dq.empty() && arr[dq.back()] < arr[i]) {
            dq.pop_back();
        }
        dq.push_back(i);
    }
    for (; i < n; i++) {
        // 输出当前窗口的最大值
        cout << arr[dq.front()] << " ";
        // 移除窗口外的索引
        while (!dq.empty() && dq.front() <= i - k) {
            dq.pop_front();
        }
        // 维护队列单调性
        while (!dq.empty() && arr[dq.back()] < arr[i]) {
            dq.pop_back();
        }
        dq.push_back(i);
    }
    // 输出最后一个窗口的最大值
    cout << arr[dq.front()] << endl;
}

内容的提问来源于stack exchange,提问作者Quang huynh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 20:15:11