簡體   English   中英

c++ 數組 - 表達式必須有常量值

[英]c++ array - expression must have a constant value

當我嘗試從我聲明的變量創建數組時出現錯誤。

int row = 8;
int col= 8;
int [row][col];

為什么會出現此錯誤:

表達式必須有一個常量值。

創建這樣的數組時,它的大小必須是恆定的。 如果你想要一個動態大小的數組,你需要在堆上為它分配內存,你還需要在完成后用delete釋放它:

//allocate the array
int** arr = new int*[row];
for(int i = 0; i < row; i++)
    arr[i] = new int[col];

// use the array

//deallocate the array
for(int i = 0; i < row; i++)
    delete[] arr[i];
delete[] arr;

如果您想要固定大小,則必須將它們聲明為 const:

const int row = 8;
const int col = 8;
int arr[row][col];

還,

int [row][col];

甚至不提供變量名。

該標准要求數組長度是一個在編譯時可計算的值,以便編譯器能夠在堆棧上分配足夠的空間。 在您的情況下,您試圖將數組長度設置為編譯時未知的值。 是的,我知道編譯器應該知道它似乎很明顯,但這里的情況並非如此。 編譯器不能對非常量變量的內容做出任何假設。 所以去吧:

const int row = 8;
const int col= 8;
int a[row][col];

UPD:一些編譯器實際上會允許你把它拉下來。 IIRC,g++ 有這個功能。 但是,永遠不要使用它,因為您的代碼將變得不可跨編譯器移植。

C++ 不允許數組大小的非常量值。 這就是它的設計方式。

C99 允許數組的大小是一個變量,但我不確定它是否允許用於二維。 某些 C++ 編譯器 (gcc) 將允許將其作為擴展,但您可能需要打開編譯器選項以允許它。

我幾乎錯過了 - 你需要聲明一個變量名,而不僅僅是數組維度。

您可以使用 #define 作為替代解決方案,它不會引入 vector 和 malloc,並且您在定義數組時仍然使用相同的語法。

#define row 8
#define col 8

int main()
{
int array_name[row][col];
}

當你在這里聲明一個變量時

int a[10][10];

您告訴 C++ 編譯器您希望在運行時在程序內存中分配 100 個連續整數。 然后編譯器將為您的程序提供那么多可用內存,並且一切都很好。

但是如果你告訴編譯器

int x = 9001;
int y = 5;
int a[x][y];

編譯器無法知道您在運行時實際需要多少內存,而無需進行大量非常復雜的分析來追蹤 x 和 y 的值發生變化的每個最后位置 [如果有的話]。 C++ 和 C 不支持這種可變大小的數組,強烈建議您使用 malloc() 手動分配所需的空間。

TL; 博士

int x = 5;
int y = 5;
int **a = malloc(x*sizeof(int*));
for(int i = 0; i < y; i++) {
    a[i] = malloc(sizeof(int*)*y);
}

a 現在是大小為 5x5 的二​​維數組,其行為與 int a[5][5] 相同。 因為您手動分配了內存,C++ 和 C 也要求您手動刪除它...

for(int i = 0; i < x; i++) {
    free(a[i]); // delete the 2nd dimension array
}
free(a); // delete a itself

還可以使用固定長度的向量並通過索引訪問它

int Lcs(string a, string b) 
{
    int x = a.size() + 1;
    int y = b.size() + 1;

    vector<vector<int>> L(x, vector<int>(y));

    for (int i = 1; i < x; i++)
    {
        for (int j = 1; j < y; j++)
        {
            L[i][j] = a[i - 1] == b[j - 1] ?
                L[i - 1][j - 1] + 1 :
                max(L[i - 1][j], L[i][j - 1]);
        }
    }

    return L[a.size()][b.size()];
}

使用 GCC 編譯器(我在本地完成)和在線編譯器(鏈接),與問題中運行的代碼類似的代碼提供了一個變量名稱。

#include<iostream>

int main(){
    int r= 2, c=3;
    int arr[r][c];
    arr[0][1]= 3;
    std::cout<<arr[0][1];
}

輸出: 3

雖然我引用cplusplus.com

注意:方括號 [] 中的元素字段表示數組中元素的數量,必須是一個常量表達式,因為數組是靜態內存塊,其大小必須在程序運行前的編譯時確定。

目前的編譯器似乎在這方面有所改變。 這是一個 C99 標准,標准編譯器的維護者添加到他們的編譯器中。

我們不需要 const 聲明。 在編譯期間,編譯器會自動替換該值。

這個問題圍繞這個話題展開。

注意:這不是標准的編碼實踐,因此某些編譯器可能仍會拋出錯誤。

當我創建這樣的數組時。

int a = 8;

int b[a];

它給了我一個 C2131 和一個 E0028 錯誤。 這就是為什么我害怕在 C++ 中使用數組並使用向量代替。 但是當我四處挖掘時,我發現了這個簡單的解決方案! 而不是使用上面的例子,使用這個。

int a = 8;

int* b = new int[a];

突然錯誤消失了,我的陣列完全按照預期工作。 如果你想要一個二維數組,這里是如何

int a = 8, b = 8;

int** c = new int* [a](new int[b](0));

不,它不需要是常量,他上面的代碼錯誤的原因是因為他需要在聲明之前包含一個變量名。

int row = 8;
int col= 8;
int x[row][col];

在編譯和運行沒有任何問題的 Xcode 中,在 .NET 中的 M$ C++ 編譯器中它不會編譯,它會抱怨你不能使用非 const 文字來初始化數組,需要在編譯時知道大小

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM