c++ array – expressie moet een constante waarde hebben

Ik krijg een foutmelding wanneer ik een array probeer te maken van de variabelen die ik heb gedeclareerd.

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

Waarom krijg ik deze foutmelding:

expressie moet een constante waarde hebben.


Antwoord 1, autoriteit 100%

Als je zo’n array maakt, moet de grootte constant zijn. Als je een array van dynamisch formaat wilt, moet je er geheugen voor op de heap toewijzen en je moet het ook vrijmaken met deleteals je klaar bent:

//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;

Als u een vaste maat wilt, moet u deze als const aangeven:

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

Ook

int [row][col];

geeft niet eens een variabelenaam.


Antwoord 2, autoriteit 40%

De standaard vereist dat de arraylengte een waarde is die tijdens het compileren kan worden berekend, zodat de compiler voldoende ruimte op de stapel kan toewijzen. In uw geval probeert u de arraylengte in te stellen op een waarde die tijdens het compileren onbekend is. Ja, ik weet dat het voor de hand liggend lijkt dat het bekend moet zijn bij de compiler, maar dit is hier niet het geval. De compiler kan geen aannames doen over de inhoud van niet-constante variabelen. Dus ga met:

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

UPD: met sommige compilers kun je dit echt voor elkaar krijgen. IIRC, g++ heeft deze functie. Gebruik het echter nooit, omdat uw code dan niet meer overdraagbaar is tussen compilers.


Antwoord 3, autoriteit 30%

C++ staat geen niet-constante waarden toe voor de grootte van een array. Zo is het ook ontworpen.

C99 staat toe dat de grootte van een array een variabele is, maar ik weet niet zeker of dit is toegestaan ​​voor twee dimensies. Sommige C++-compilers (gcc) staan ​​dit toe als extensie, maar het kan zijn dat u een compiler-optie moet inschakelen om dit toe te staan.

En ik miste het bijna – je moet een variabelenaam declareren, niet alleen de arraydimensies.


Antwoord 4, autoriteit 11%

Je kunt #define gebruiken als een alternatieve oplossing, die geen vector en malloc introduceert, en je gebruikt nog steeds dezelfde syntaxis bij het definiëren van een array.

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

Antwoord 5, autoriteit 10%

Als je een variabele declareert zoals hier

int a[10][10];

je vertelt de C++-compiler dat je tijdens runtime 100 opeenvolgende gehele getallen in het geheugen van het programma wilt hebben. De compiler zorgt er dan voor dat je programma zoveel geheugen beschikbaar heeft en alles is goed met de wereld.

Als je het de compiler echter vertelt

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

de compiler weet op geen enkele manier hoeveel geheugen je daadwerkelijk nodig hebt tijdens runtime zonder een heleboel zeer complexe analyses uit te voeren om elke laatste plaats op te sporen waar de waarden van x en y zijn veranderd [indien aanwezig]. In plaats van dergelijke arrays met variabele grootte te ondersteunen, raden C++ en C sterk aan, zo niet ronduit, te eisen dat u malloc() gebruikt om handmatig de gewenste ruimte toe te wijzen.

TL;DR

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 is nu een 2D-array van de grootte 5×5 en zal zich hetzelfde gedragen als int a[5][5]. Omdat je handmatig geheugen hebt toegewezen, eisen C++ en C dat je het ook met de hand verwijdert…

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

Antwoord 6, autoriteit 2%

je zou ook een vector met een vaste lengte kunnen gebruiken en deze openen met indexering

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()];
}

Antwoord 7, autoriteit 2%

Met behulp van de GCC-compiler (die ik lokaal heb gedaan) en een online compiler (link), een code vergelijkbaar met die in de vraaguitvoeringen leverde een variabelenaam op.

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

Uitvoer: 3

Hoewel ik cplusplus.comciteer,

OPMERKING: Het elementenveld tussen vierkante haken [], dat het aantal elementen in de array vertegenwoordigt, moet een constante uitdrukking zijn, aangezien arrays blokken statisch geheugen zijn waarvan de grootte moet worden bepaald tijdens het compileren voordat het programma wordt uitgevoerd.

Het lijkt erop dat de huidige compilers in dit opzicht zijn gewijzigd. Dit is een C99-standaard die de beheerders van de standaardcompilers aan hun compilers hebben toegevoegd.

We hebben geen const-verklaring nodig. Tijdens het compileren vervangt de compiler automatisch de waarde.

Dezevraag gaat rond het onderwerp.

OPMERKING: dit is niet de standaard coderingspraktijk, dus sommige compilers kunnen nog steeds een fout geven.


Antwoord 8

Nee, het hoeft niet constant te zijn, de reden waarom zijn code hierboven verkeerd is, is omdat hij een variabelenaam moet opnemen voor de declaratie.

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

In Xcode die zonder problemen wordt gecompileerd en uitgevoerd, in de M$ C++-compiler in .NET zal het niet compileren, het zal klagen dat je geen niet-const-literal kunt gebruiken om de array te initialiseren, de grootte moet bekend zijn op compileertijd

Other episodes