2012-11-08 26 views
10

से सरणी तत्वों के मानों को बदलने में मैं सी ++ (प्रत्येक नौसिखिया एक्सडी के लिए सामान्य परिचय) में नया हूं। खैर, मैं एक कार्यक्रम विकसित कर रहा था, जब एक अप्रत्याशित व्यवहार दिखाया गया !! मैंने अपने कार्यक्रम में चर और सरणी का पता लगाया जब तक कि मैं इस व्यवहार को करने वाले कोड के पैटर्न को निर्धारित करने में सफल नहीं हुआ !!फ़ंक्शन

#include <iostream> 

using namespace std; 

void showArray(int arr[], int n) 
{ 
    for(int i = 0; i < n; i++) cout << arr[i] << " "; 
    cout << endl; 
} 
void someFunction(int x[], int n) // changes the original values 
{ 
    x[0] = 2; 
    x[1] = 1; 
    x[2] = 0; 
} 
void someFunction2(int * x, int n) 
{ 
    x[0] = 2; 
    x[1] = 1; 
    x[2] = 0; 
} // changes the original values 
int someFunction3(int x[], int n) 
{ 
    x[0] = 2; 
    x[1] = 1; 
    x[2] = 0; 
    return 0; 
} // changes the original values 
int someFunction4(int x[], int n) 
{ 
    x = new int[n]; 
    x[0] = 2; 
    x[1] = 1; 
    x[2] = 0; 
    return 0; 
} // does NOT change the original value 

int main(void) 
{ 
    int * y = new int[3]; 
    y[0] = 0; 
    y[1] = 1; 
    y[2] = 2; 
    showArray(y, 3); 
    someFunction4(y, 3); 
    showArray(y, 3); 
    return 0; 
} 

मुझे लगता है कि टिप्पणी के साथ कोड बताते हैं जहां समस्या है, लेकिन अधिक जानकारी है::

यहाँ कि जो मैं पता लगाने के लिए कैसे चीजें काम का इस्तेमाल किया है है वहाँ 4 कार्य हैं, अर्थात्, someFunction , कुछ फ़ंक्शन 2, कुछ फ़ंक्शन 3, कुछ फ़ंक्शन 4। वहाँ एक सरणी है, y, जिसमें मान 0, 1, 2. सभी फ़ंक्शन मूल सरणी के मान को बदलते हैं। यही है, कुछ फ़ंक्शनक्शन कॉल कॉल के बाद मुख्य फ़ंक्शन में वाई के तत्व फ़ंक्शन को कॉल करने से पहले थे।

मेरा प्रश्न है: क्यों कुछ फ़ंक्शन 4 एकमात्र फ़ंक्शन है जो मानों को परिवर्तित नहीं करता है?

अग्रिम धन्यवाद। और मेरी बुरी अंग्रेजी के लिए खेद है।

उत्तर

7

someFunction4 में, आप x को new पूर्णांक के सरणी को इंगित करने के लिए असाइन करते हैं, जिसे आप तब असाइन करते हैं। आपके द्वारा फ़ंक्शन में पारित चर द्वारा इंगित सरणी अभी भी पुरानी सरणी को इंगित करती है। पुरानी सरणी अपरिवर्तित रहता है, क्योंकि someFunction4 के भीतर आपने x को एक अलग सरणी के संदर्भ में सेट किया है, अर्थात् जिसे आपने अपने फ़ंक्शन में new के माध्यम से बनाया है।

1) x = new int[n]; से छुटकारा:

आदेश someFunction4() में मूल x बनाने के लिए ये मान सौंपा पकड़, दो चीजों में से एक है। यह someFunction4() पिछले लोगों की तरह काम करेगा।

2) पर someFunction4() पर एक तर्क के रूप में एक पॉइंटर पास करें और someFunction4() एक पॉइंटर लें।

int someFunction4(int *x[], int n) 
{ 
    *x = new int[n]; 
    (*x)[0] = 2; 
    (*x)[1] = 1; 
    (*x)[2] = 0; 
    return 0; 
} // Makes x point to a new a new array 

और अपने मुख्य में, कर

someFunction4(&y,3); 
+0

धन्यवाद। आपका जवाब स्पष्ट है। तो, पुराने सरणी को नया मूल्य कैसे लेना है? – joker

+0

असाइनमेंट से छुटकारा पाएं 'x = new int [n]; ' – GraphicsMuncher

+0

क्या होगा यदि मैं फ़ंक्शन के भीतर से सरणी आकार को बदलना चाहता हूं? – joker

0

आप को समझने के लिए तर्क कार्यों

को पास किया जाता जब आप SomeFunctionN कॉल (y, 3) तो SomeFunctionN अंदर 'एक्स' वैरिएबल एक स्थानीय चर है जो उसी सरणी पर इंगित करने के लिए शुरू किया गया है जो y मुख्य रूप से इंगित कर रहा था।

कुछफनक 4 में आप फिर एक नई सरणी बनाते हैं और आपको नए सूचकांक पर इंगित करने के लिए स्थानीय सूचक (x) बदलते हैं। सभी परिवर्तन आप नई सरणी

हिट कर अन्य सभी मामलों में आप एक्स छोड़ अकेले

2

मैं एक testcase बनाया है।

http://ideone.com/fyl6MX

परिणाम

0 1 2 
0x943b008 
0x943b018 
0x943b008 
0 1 2 

दूसरा एक पते नई तालिका के पते है।जैसा कि आप देख सकते हैं कि आपका पॉइंटर स्थानीय रूप से अन्य पते पर इंगित कर रहा है।

#include <iostream> 

using namespace std; 

void showArray(int arr[], int n) 
{ 
    for(int i = 0; i < n; i++) cout << arr[i] << " "; 
    cout << endl; 
} 
void someFunction(int x[], int n) // changes the original values 
{ 
    x[0] = 2; 
    x[1] = 1; 
    x[2] = 0; 
} 
void someFunction2(int * x, int n) 
{ 
    x[0] = 2; 
    x[1] = 1; 
    x[2] = 0; 
} // changes the original values 
int someFunction3(int x[], int n) 
{ 
    x[0] = 2; 
    x[1] = 1; 
    x[2] = 0; 
    return 0; 
} // changes the original values 
int someFunction4(int x[], int n) 
{ 
    x = new int[n]; 
    std::cout << x << endl; 
    x[0] = 2; 
    x[1] = 1; 
    x[2] = 0; 
    return 0; 
} // does NOT change the original value 

int main(void) 
{ 
    int * y = new int[3]; 
    y[0] = 0; 
    y[1] = 1; 
    y[2] = 2; 
    showArray(y, 3); 

    std::cout << y << endl; 

    someFunction4(y, 3) ; 
    std::cout << y << endl; 

    showArray(y, 3); 
    return 0; 
} 
+0

तो फ़ंक्शन के भीतर से मूल पॉइंटिंग मान को कैसे बदला जाए? – joker

5

someFunction, someFunction2 से प्रत्येक में, और someFunction3, आप वास्तव में स्मृति आप main() में अपने सरणी के लिए आवंटित करने के लिए एक pointer गुजर रहे हैं। इसका मतलब यह है कि जब आप करने के लिए डेटा पर इस सूचक अंक संचालित: यह वास्तव में एक ही स्मृति कि y अंक main() में वापस करने के लिए प्रभावित करता

x[1] = 1; 

!

हालांकि, someFunction4 में, आप बयान के साथ नई स्मृति को इंगित करने के पुन: असाइन सूचक x:

x = new int[n]; 

तो यह एक ही याद है कि ymain() में करता है, और कोई भी परिवर्तन करने के लिए नहीं रह अंक इसके बाद आप इसे बनाते हैं (लेकिन केवल someFunction4 के दायरे में!) y को प्रभावित नहीं करेगा।