2014-10-30 7 views
48

मैं सी ++ में कोडिंग कर रहा हूं। अगर मेरे पास कुछ फ़ंक्शन void foo(vector<int> test) है और मैं इसे अपने प्रोग्राम में कॉल करता हूं, तो क्या वेक्टर मूल्य या संदर्भ से गुज़रेंगे? मुझे अनिश्चितता है क्योंकि मुझे पता है कि वेक्टर और सरणी समान हैं और void bar(int test[]) जैसे फ़ंक्शन मूल्य के बजाय संदर्भ (सूचक?) द्वारा परीक्षण पास करेंगे। मेरा अनुमान है कि अगर मैं मूल्य से गुजरने से बचाना चाहता हूं तो मुझे संकेतक/संदर्भ द्वारा वेक्टर को पारित करने की आवश्यकता होगी, लेकिन मुझे यकीन नहीं है।एक समारोह में वैक्टर पास करने, मूल्य बनाम संदर्भ सी ++

+5

सी ++ "मूल्य से गुजरती हैं" है अर्थशास्त्र, तो यह मूल्य से पारित किया जाता है। हालांकि आप संदर्भ से गुजरने का फैसला कर सकते हैं। पसंद वास्तव में इस बात पर निर्भर करता है कि समारोह क्या करता है। – juanchopanza

+1

संदर्भ द्वारा उपयोग करें, यदि आप वेक्टर सामग्री को बदलने के लिए फ़ंक्शन नहीं चाहते हैं तो इसे कॉन्स्ट बनाएं, अन्यथा बस इसे संदर्भ द्वारा पास करें। यह अन-वांछित और महंगा (कभी-कभी) प्रतिलिपि –

+2

से बच जाएगा, इसके अलावा, एक संदर्भ एक सूचक नहीं है। –

उत्तर

66

अगर मुझे लगता है, तो मैं कहूंगा कि आप जावा पृष्ठभूमि से हैं। यह सी ++ है, और चीजें मूल्य से गुजरती हैं जबतक कि आप &-ऑपरेटर का उपयोग करके अन्यथा निर्दिष्ट नहीं करते हैं (ध्यान दें कि इस ऑपरेटर को 'एड्रेस ऑफ' ऑपरेटर के रूप में भी उपयोग किया जाता है, लेकिन एक अलग संदर्भ में)। यह सब अच्छी तरह से प्रलेखित है, लेकिन मैं वैसे भी फिर से पुनरावृति होगी:

void foo(vector<int> bar); // by value 
void foo(vector<int> &bar); // by reference (non-const, so modifyable inside foo 
void foo(vector<int> const &bar); // by const-reference 

तुम भी एक सदिश (void foo(vector<int> *bar)) के सूचक के पारित करने के लिए चुन सकते हैं, लेकिन जब तक आप जानते हैं कि आप क्या कर रहे हैं और आपको लगता है कि लग रहा है यह वास्तव में जाने का रास्ता है, ऐसा मत करो।

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

मेरा सुझाव है कि आप सामान्य (विशेष रूप से array decay) में सी के बारे में ++ और कुछ अधिक पढ़ सकते हैं, और फिर निम्न प्रोग्राम है जो सरणियों और संकेत के बीच अंतर को दिखाता है पर एक नजर है:

void foo1(int *arr) { cout << sizeof(arr) << '\n'; } 
void foo2(int arr[]) { cout << sizeof(arr) << '\n'; } 
void foo3(int arr[10]) { cout << sizeof(arr) << '\n'; } 
void foo4(int (&arr)[10]) { cout << sizeof(arr) << '\n'; } 

int main() 
{ 
    int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 
    foo1(arr); 
    foo2(arr); 
    foo3(arr); 
    foo4(arr); 
} 
+13

आपने मुझे प्राप्त किया। जावा पृष्ठभूमि। –

+2

क्या कोई मुझे अंतिम घोषणा foo4 फ़ंक्शन को समझने में सहायता कर सकता है? यह अन्य कार्यों में सूचक के आकार के बजाय सरणी का आकार क्यों लौटाता है? –

+1

@abhishek_M क्योंकि पैरामीटर प्रकार एक संदर्भ है। एक संदर्भ केवल उसी प्रकार की अभिव्यक्ति के लिए बाध्य किया जा सकता है। इस कारण से सरणी क्षय नहीं होती है, क्योंकि किसी सरणी के संदर्भ को पॉइंटर से बाध्य नहीं किया जा सकता है, यह केवल उसी प्रकार की सरणी से जुड़ा हो सकता है (इस मामले में 10 पूर्णांक की सरणी) – bolov

5

void foo(vector<int> test)

वेक्टर इस में मूल्य द्वारा पारित किया जाएगा।

1) संदर्भ को पार करें: - -:

आप संदर्भ के आधार पर वैक्टर पारित करने के लिए अधिक रास्ते होंगे इस समारोह foo वेक्टर की अपनी सामग्री को बदल देंगे। वेक्टर की प्रतिलिपि के रूप में मूल्य से गुजरने से अधिक कुशलता से बचा जाता है।

2) कॉन्स्ट-रेफरेंस द्वारा पास: - यह कुशल और भरोसेमंद है जब आप वेक्टर की सामग्री को बदलने के लिए फ़ंक्शन नहीं करना चाहते हैं।

7

vector एक सरणी के रूप में कार्यात्मक रूप से समान है। लेकिन, vector भाषा में एक प्रकार है, और int भी एक प्रकार है। फ़ंक्शन तर्क के लिए, किसी भी प्रकार की सरणी (vector[] सहित) को पॉइंटर के रूप में माना जाता है। vector<int>int[] (कंपाइलर के लिए) के समान नहीं है। vector<int> गैर-सरणी, गैर-संदर्भ, और गैर-सूचक है - यह मान द्वारा पारित किया जा रहा है, और इसलिए यह कॉपी-कन्स्ट्रक्टर को कॉल करेगा।

तो, आपको संदर्भ के रूप में पास करने के लिए vector<int>& (अधिमानतः const के साथ, यदि फ़ंक्शन इसे संशोधित नहीं कर रहा है) का उपयोग करना चाहिए।

+0

फ़ंक्शन के संदर्भ में "वेक्टरों की सरणी" को पारित करने के लिए वाक्यविन्यास क्या है? – ab123

+0

शून्य फ़ंक्शननाम (std :: वेक्टर (& vc) [5]) {} – RIanGillis

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