2010-02-20 16 views
7

मान लीजिए मैं मैं सी में एक सरणी लौटें ++

int& function(int arr[]) 
{ 
//rest of the code 
     return arr; 
} 

क्या गलती मैं यहाँ पर कर रही हूँ

के रूप में कार्य हो एक सरणी

int arr[] = {...}; 
arr = function(arr); 

है ??

+2

आप (या सिर्फ कोई डेवलपर) इस पागल कोड को क्यों लिख रहे हैं? : \ – kennytm

+0

@ manugupt1: क्या यह आपके इरादे को एक प्रतिलिपि के रूप में फ़ंक्शन में पास करने का इरादा है? –

उत्तर

7
int& function(int arr[]) 

इस समारोह आगमन में खत्म करने एक सूचक है, और वहाँ कोई रास्ता नहीं इसे वापस एक सरणी के लिए फिर से चालू करने के लिए है। यह

int& function(int* arr) 

int arr[] = {...}; 
arr = function(arr); 

मान लिया जाये कि समारोह सरणी के लिए एक संदर्भ वापसी करने में कामयाब रहे की तरह ही है यह अभी भी काम नहीं होता। आप एक सरणी को असाइन नहीं कर सकते हैं। सबसे अच्छा में आप एक "एक्स ints की एक सरणी के संदर्भ" के लिए परिणाम के लिए बाध्य कर सकता है (एक typedef का उपयोग कर, क्योंकि वाक्य रचना अन्यथा बहुत बदसूरत मिलेगा):

typedef int ten_ints[10]; 

ten_ints& foo(ten_ints& arr) 
{ 
    //.. 
    return arr; 
} 

int main() 
{ 
    int arr[10]; 
    ten_ints& arr_ref = foo(arr); 
} 

हालांकि, यह पूरी तरह से स्पष्ट नहीं है में क्या कोड है अपने प्रश्न प्राप्त करने के लिए माना जाता है। फ़ंक्शन में सरणी में किए गए कोई भी परिवर्तन कॉलर को दिखाई देंगे, इसलिए सरणी को वापस करने का प्रयास करने या मूल सरणी पर वापस असाइन करने का कोई कारण नहीं है।


आप एक निश्चित आकार सरणी है कि आप को असाइन करने और मूल्य द्वारा पारित कर सकते हैं चाहते हैं (साथ सामग्री कॉपी की जा रही), वहाँ std::tr1::array (या boost::array) है। std::vector भी एक विकल्प है, लेकिन यह एक गतिशील सरणी है, इसलिए सटीक समतुल्य नहीं है।

1
  • तर्क के रूप में एक सरणी वास्तव में एक सूचक है। तर्क
  • के रूप में दिए जाने पर Arrays को पॉइंटर्स पर स्वचालित रूप से 'जाली' कर दिया जाता है आप सी/सी ++ में किसी अन्य सरणी को सरणी निर्दिष्ट नहीं कर सकते हैं। मूल्यों की प्रतिलिपि बनाने के लिए आपको एक memcpy या लूप का उपयोग करना होगा।
  • यदि फ़ंक्शन एआर तर्क बदलता है, तो यह वास्तव में कॉलर द्वारा दिए गए एआर चर के मान को बदल देता है। फिर से क्योंकि सरणी वास्तव में एक सूचक है। तो कॉलर एआर में एआर को सौंपा गया है, जो यहां बेकार है।
4

सरणी पास करने और वापसी के अर्थशास्त्र काफी भ्रमित हो सकते हैं। इसके बजाय एक std :: वेक्टर का प्रयोग करें।

+0

या बूस्ट :: सरणी, अगर यह उपलब्ध है। – Macke

+9

हालांकि यह निश्चित रूप से अच्छी सलाह है, ** यह दूरस्थ रूप से प्रश्न का उत्तर भी नहीं देता ** ** –

+0

@Andreas "मैं यहां क्या गलती कर रहा हूं ??" - वेक्टर का उपयोग न करने की गलती। –

3

आप एक int के संदर्भ को वापस कर रहे हैं, एक सरणी के संदर्भ नहीं।

आप चाहते हैं:

(int*)& function(int arr[]) 
{ 
    /// rest of the code 
    return arr; 
} 

जिसके अनुसार, के रूप में दूसरों को पहले से ही कहा, कि नहीं अच्छी आदत है।

+3

दरअसल जो एक सूचक और 'arr' का संदर्भ देता है, वह एक सरणी नहीं है। –

+1

@gf कहता है कि यह भी एक वाक्यविन्यास त्रुटि है। –

0

ठीक है, एआर int* के साथ संगत है, int& नहीं। आपका कोड संकलित नहीं होगा। शायद आप return arr[0] चाहते थे?

0

आप सी ++ में किसी अन्य सरणी को सरणी निर्दिष्ट नहीं कर सकते हैं। एसटीएल वेक्टर का उपयोग करने पर विचार करें: http://www.cplusplus.com/reference/stl/vector/

6

जैसा कि अन्य ने कहा है, एसटीएल कंटेनर जैसे बेहतर विकल्प हैं और सबसे दिलचस्प सवाल यह है कि आपको सरणी को उस फ़ंक्शन में वापस करने की आवश्यकता क्यों है जो पहले से ही इसे दायरे में रखती है।

कहा जा रहा है, तो आप पारित नहीं हो सकता या मूल्य द्वारा सरणियों लौट सकते हैं और सरणी एक सूचक को खस्ताहाल से बचने की जरूरत है (देखें उदाहरण के लिए here), या तो उससे संकेतक या संदर्भ का उपयोग करके:

int (&f(int (&arr)[3]))[3] 
{ 
    return arr; 
} 

आप आकार हार्ड-कोड नहीं करना चाहते हैं, तो आप टेम्पलेट कार्यों का उपयोग कर सकते हैं: std :: इस तरह वेक्टर

template<size_t n> 
int (&f(int (&arr)[n]))[n] 
{ 
    return arr; 
} 
+0

यह कुछ गंभीरता से _twisted_ वाक्यविन्यास है। आप इसे यहां तक ​​पहुंचने के लिए बहुत सारे कुडोस के लायक हैं। मैं अब टाइपिफ्स का उपयोग करने के लिए स्वतंत्र महसूस करता हूं कि मुझे पता है कि आप संभवत: कंपाइलर के बिना वर्तनी के लिए वर्तनी कर सकते हैं। +1 – sehe

+0

मान लीजिए कि मैं एक निश्चित आकार सरणी के लिए गेटर को कोड करना चाहता हूं और विधि के साथ-साथ संदर्भित सरणी चाहता हूं कॉन्स्टैक्टिक रूप से मैं कैसे करूं? इस तरह: int const (और GetArray() const) [3] {वापसी mArray; }? – Bjoern

+0

@Bjoern: 'typedef int ए [3]; कॉन्स ए एम; कॉन्स ए और एफ() कॉन्स {वापसी एम; } '? –

0

का प्रयोग करें।

std::vector<int> function(const std::vector<int>& arr) 
{ 
    return arr; 
} 

तरह

int arr[] = {...}; 

एक सरणी उपयोगी नहीं है एक समारोह है क्योंकि इसकी स्वयं की कॉपी करने में सक्षम नहीं से लौटे किया जाना है।

0

यदि आवश्यक नहीं है, तो इसका उपयोग न करें।

void foo(std::vector<int> &v) { 
    for (int i = 0; i < 10; ++ i) { 
     v.push_back(i); 
    } 
} 

अगर आप का उपयोग करें:: तुम सिर्फ इस तरह के रूप एक सरणी के संदर्भ पारित कर सकते हैं,

std::vector<int> foo() { 
    std::vector<int> v; 
    for (int i = 0; i < 10; ++ i) 
     v.push_back(i); 

    return v; 
} 

वहाँ कंटेनर की एक प्रति प्रक्रिया हो जाएगा, लागत महंगी है।

FYI करें: NRVO शायद लागत

1

मुझे लगता है कि आपकी सबसे अच्छी शर्त इसे एक सरणी के सूचक के रूप में वापस करने के लिए है। यहाँ एक उदाहरण है:

{ 
    ... 
    int newLength = 0; 
    int* arr2 = ChangeArray(arr, length, newLength); 
    ... 
    delete[] arr2; 
} 

int* ChangeArray(int arr[], int length, int& newLength) 
{ 
    // reversing the number - just an example 
    int* newArr = new int[length]; 
    for(int i = 0; i < length; i++) 
    { 
     newArr[i] = arr[length-i-1]; 
     newLength++; 
    } 
    return newArr; 
} 
3

के बाद काम करता है और गंदा या गलत समझा जा सकता प्रतीत नहीं होता!

int* returnarray(int a[]) 
{ 
    for (unsigned int i = 0; i < 3; i++) 
    { 
     a[i] *= 2; 
    } 
    return a; 
} 

int main(int argc, char* argv[]) 
{ 
    int arr[3] = {1,2,3}; 
    int* p = returnarray(arr); 
    for (unsigned int i = 0; i < 3; i++) 
    { 
     cout << "p[" << i << "] = " << p[i] << endl; 
    } 
     cin.get(); 
     return 0; 
} 
संबंधित मुद्दे