2012-02-09 18 views
24

मुझे एक त्रुटि मिलती है जब मैं घोषित चर से सरणी बनाने का प्रयास करता हूं।सी ++ सरणी - अभिव्यक्ति का निरंतर मान होना चाहिए

expression must have a constant value.

+0

'int [row] [col];' क्या करने की अपेक्षा है, ठीक है? –

+0

यहां सूचीबद्ध अच्छी सी ++ किताबें: http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list –

+5

अपने प्रश्न के कोड को ठीक से संपादित न करें; इससे भविष्य में पाठकों के लिए आपका प्रश्न बेहद भ्रमित हो जाता है। – ildjarn

उत्तर

14

सी ++ एक सरणी के आकार के लिए गैर-निरंतर मूल्यों अनुमति नहीं देता:

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

मैं यह त्रुटि क्यों मिलता है। यही वह तरीका है जिस तरह से इसे डिजाइन किया गया था।

सी 99 एक सरणी के आकार को एक चर होने की अनुमति देता है, लेकिन मुझे यकीन नहीं है कि इसे दो आयामों के लिए अनुमति है। कुछ सी ++ कंपाइलर्स (जीसीसी) इसे एक एक्सटेंशन के रूप में अनुमति देंगे, लेकिन आपको इसे अनुमति देने के लिए एक कंपाइलर विकल्प चालू करने की आवश्यकता हो सकती है।

और मुझे लगभग इसे याद आया - आपको सरणी आयामों के बजाय एक चर नाम घोषित करने की आवश्यकता है।

+0

"लेकिन मुझे यकीन नहीं है कि इसे दो आयामों के लिए अनुमति है" - यह है। सी के लिए, जैसा कि आपने नोट किया है, सी ++ के लिए नहीं। – hvd

+0

@ एचवीडी, स्पष्टीकरण के लिए धन्यवाद। इन दिनों शुद्ध सी के लिए मेरा संपर्क दुखद रूप से सीमित है। –

29

इस तरह की सरणी बनाते समय, इसका आकार स्थिर होना चाहिए। तो

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

आप एक निश्चित आकार चाहते हैं,: यदि आप एक गतिशील आकार सरणी चाहते हैं, आप ढेर पर इसके लिए स्मृति को आबंटित करने की जरूरत है और आप भी यह करने के बाद delete साथ यह खाली करना होगा

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

इसके अलावा,

int [row][col]; 

भी एक चर नाम प्रदान नहीं करता है: वे स्थिरांक घोषित किया जाना चाहिए।

+4

शायद दिखाएं कि स्मृति को कैसे हटाएं, आह? ;) – monoceres

8

मानक के लिए सरणी लंबाई को एक मान होने की आवश्यकता होती है जो संकलन समय पर गणना योग्य है ताकि संकलक ढेर पर पर्याप्त स्थान आवंटित करने में सक्षम हो। आपके मामले में, आप सरणी की लंबाई को उस मान पर सेट करने का प्रयास कर रहे हैं जो संकलित समय पर अज्ञात है। हां, मुझे पता है कि यह स्पष्ट प्रतीत होता है कि इसे कंपाइलर के लिए जाना जाना चाहिए, लेकिन यह मामला यहां नहीं है। कंपाइलर गैर-निरंतर चर की सामग्री के बारे में कोई धारणा नहीं बना सकता है। तो साथ जाएं:

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

यूपीडी: कुछ कंपाइलर्स वास्तव में आपको इसे खींचने की अनुमति देंगे। आईआईआरसी, जी ++ में यह सुविधा है। हालांकि, इसका कभी भी उपयोग न करें क्योंकि आपका कोड कंपेलरों में अन-पोर्टेबल बन जाएगा।

+1

सबसे संक्षिप्त और सही उत्तर। –

4

जब आप के रूप में यहाँ

int a[10][10]; 

आप C++ कम्पाइलर कि आप चाहते हैं 100 लगातार क्रम में कार्यक्रम की स्मृति में आवंटित पूर्णांकों कह रहे हैं एक चर घोषणा करते हैं। संकलक तब आपके प्रोग्राम को उस स्मृति को उपलब्ध कराने के लिए प्रदान करेगा और सब कुछ दुनिया के साथ अच्छा होगा।

यदि फिर भी आप संकलक

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

संकलक बहुत जटिल विश्लेषण की एक बहुत कुछ कर के बिना जानते हुए भी कितना स्मृति आप वास्तव में रन टाइम पर की जरूरत करने जा रहे हैं का कोई रास्ता नहीं हर अंतिम स्थान को ट्रैक करने की है बता जहां एक्स और वाई के मान बदल गए [यदि कोई हैं]। ऐसे परिवर्तनीय आकार सरणी का समर्थन करने के बजाय, सी ++ और सी दृढ़ता से सुझाव देते हैं कि अगर आप चाहते हैं कि मैन्युअल रूप से आवंटित करने के लिए आप malloc() का उपयोग नहीं करते हैं।

टी एल; डॉ

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

एक अब आकार 5x5 के एक 2 डी सरणी है और पूर्णांक के रूप में ही व्यवहार करेंगे एक [5] [5]। क्योंकि आप मैन्युअल रूप से स्मृति आवंटित, सी ++ और सी मांग आप हाथ भी कर इसे नष्ट कि ...

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

आपका उत्तर मान्य नहीं है C++: आप 'शून्य *' से 'int *' और 'int **' से एक अंतर्निहित रूपांतरण पर भरोसा कर रहे हैं। और निश्चित रूप से, यदि आप एक कास्ट जोड़ते हैं, तो अभी भी 'malloc' का उपयोग करने के लिए यह अभी भी खराब शैली है। – hvd

-2

कोई यह निरंतर होने की जरूरत नहीं है, कारण है कि अपने कोड के ऊपर गलत है क्योंकि वह की जरूरत है घोषणा से पहले एक परिवर्तनीय नाम शामिल करने के लिए।

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

Xcode जो .NET में संकलन और बिना किसी समस्या के चलेंगे, एम $ सी ++ संकलक में यह संकलन नहीं होगा में, यह शिकायत करेगा कि आप सरणी, आकार की जरूरत प्रारंभ करने में एक गैर स्थिरांक शाब्दिक उपयोग नहीं कर सकते संकलन समय

7

आप # वैकल्पिक विकल्प के रूप में परिभाषित कर सकते हैं, जो वेक्टर और मॉलोक पेश नहीं करते हैं, और आप अभी भी एक सरणी को परिभाषित करते समय एक ही वाक्यविन्यास का उपयोग कर रहे हैं।

#define row 8 
#define col 8 

int main() 
{ 
int array_name[row][col]; 
} 
संबंधित मुद्दे

 संबंधित मुद्दे