c++ - जब किसी फ़ंक्शन में विशिष्ट-आकार सरणी पैरामीटर होता है, तो इसे पॉइंटर के साथ क्यों बदला जाता है?




arrays standards sizeof function-parameter (4)

निम्नलिखित कार्यक्रम को देखते हुए,

#include <iostream>

using namespace std;

void foo( char a[100] )
{
    cout << "foo() " << sizeof( a ) << endl;
}

int main()
{
    char bar[100] = { 0 };
    cout << "main() " << sizeof( bar ) << endl;
    foo( bar );
    return 0;
}

आउटपुट

main() 100
foo() 4
  1. सरणी पहले तत्व के लिए सूचक के रूप में क्यों पारित किया जाता है?
  2. क्या यह सी से विरासत है?
  3. मानक क्या कहता है?
  4. सी ++ की सख्त प्रकार-सुरक्षा क्यों गिरा दी गई है?

Answers

हाँ। सी और सी ++ में आप कार्यों के लिए सरणी पास नहीं कर सकते हैं। यह वैसा ही है जैसा होना चाहिए।

आप वैसे भी सादे सरणी क्यों कर रहे हैं? क्या आपने boost / std::tr1::array / std::array या std::vector ?

ध्यान दें कि, हालांकि, आप फ़ंक्शन टेम्पलेट में मनमानी लंबाई की सरणी के संदर्भ को पास कर सकते हैं। मेरे सर के ऊपर से चला गया:

template< std::size_t N >
void f(char (&arr)[N])
{
  std::cout << sizeof(arr) << '\n';
}

हां यह सी से विरासत में मिला है समारोह:

void foo ( char a[100] );

पॉइंटर होने के लिए समायोजित पैरामीटर होगा, और ऐसा हो जाता है:

void foo ( char * a );

यदि आप चाहते हैं कि सरणी प्रकार संरक्षित है, तो आपको सरणी के संदर्भ में पास होना चाहिए:

void foo ( char (&a)[100] );

सी ++ '03 8.3.5 / 3:

... फ़ंक्शन का प्रकार निम्न नियमों का उपयोग करके निर्धारित किया जाता है। प्रत्येक पैरामीटर का प्रकार अपने स्वयं के घोषित-विनिर्देशक-सेक और घोषणाकर्ता से निर्धारित होता है। प्रत्येक पैरामीटर के प्रकार का निर्धारण करने के बाद, "सरणी की टी" या "फ़ंक्शन रिटर्निंग टी" के किसी भी पैरामीटर को क्रमशः "टी को पॉइंटर" या "लौटने वाले फ़ंक्शन को ट्यूनर" के रूप में समायोजित किया जाता है ....

वाक्यविन्यास की व्याख्या करने के लिए:

Google में "दाएं-बाएं" नियम की जांच करें; मुझे here इसका एक विवरण मिला।

यह इस उदाहरण पर लगभग निम्नानुसार लागू किया जाएगा:

void foo (char (&a)[100]);

पहचानकर्ता 'ए' पर शुरू करें

'ए' एक है

दाएं स्थानांतरित करें - हमें एक मिल गया है ) इसलिए हम दिशा को पीछे की तरफ देख रहे हैं ( जैसे हम बाईं ओर जाते हैं हम पास करते हैं &

'ए' एक संदर्भ है

हम खोलने तक पहुंचते हैं ( इसलिए हम फिर से उलटते हैं और सही दिखते हैं। अब हम देखते हैं [100]

'ए' 100 की सरणी का संदर्भ है

और जब तक हम char तक नहीं पहुंच जाते, हम फिर से दिशा को उलट देते हैं:

'ए' 100 वर्णों की एक सरणी का संदर्भ है


सी / सी ++ शब्दावली में शानदार शब्द है जिसका उपयोग स्थिर सरणी और फ़ंक्शन पॉइंटर्स - क्षय के लिए किया जाता है । निम्नलिखित कोड पर विचार करें:

int intArray[] = {1, 3, 5, 7, 11}; // static array of 5 ints
//...
void f(int a[]) {
  // ...
}
// ...
f(intArray); // only pointer to the first array element is passed
int length = sizeof intArray/sizeof(int); // calculate intArray elements quantity (equals 5)
int ptrToIntSize = sizeof(*intArray); // calculate int * size on your system

इसके for...in उपयोग करना for...in किसी सरणी के लिए लूप for...in गलत नहीं है, हालांकि मुझे लगता है कि किसी ने आपको क्यों बताया है:

1.) पहले से ही एक उच्च ऑर्डर फ़ंक्शन या विधि है, जिसमें उस सरणी के लिए वह उद्देश्य है, लेकिन इसमें 'कार्यक्षमता' नामक अधिक कार्यक्षमता और दुबला वाक्यविन्यास है: Array.prototype.forEach(function(element, index, array) {} );

2.) Arrays में हमेशा एक लम्बाई होती है, लेकिन for...in और forEach लिए किसी भी मान के लिए फ़ंक्शन निष्पादित नहीं करता है जो 'undefined' , केवल उन इंडेक्स के लिए जिनके पास मान परिभाषित किया गया है। इसलिए यदि आप केवल एक मान असाइन करते हैं, तो ये लूप केवल एक बार फ़ंक्शन निष्पादित करेंगे, लेकिन चूंकि एक सरणी की गणना की जाती है, इसलिए यह हमेशा उच्चतम इंडेक्स तक लम्बाई रखती है जिसमें परिभाषित मूल्य होता है, लेकिन इन लंबाईों का उपयोग करते समय उस लंबाई को ध्यान में रखा जा सकता है लूप।

3.) लूप के लिए मानक एक पैरामीटर को निष्पादित करेगा जैसा कि आप पैरामीटर में परिभाषित करते हैं, और चूंकि एक सरणी क्रमांकित होती है, इसलिए यह परिभाषित करने में अधिक समझदारी होती है कि आप कितनी बार फ़ंक्शन निष्पादित करना चाहते हैं। अन्य लूप के विपरीत, लूप के लिए सरणी में प्रत्येक अनुक्रमणिका के लिए फ़ंक्शन निष्पादित कर सकता है, चाहे मान परिभाषित किया गया हो या नहीं।

संक्षेप में, आप किसी भी पाश का उपयोग कर सकते हैं, लेकिन आपको याद रखना चाहिए कि वे वास्तव में कैसे काम करते हैं। उन स्थितियों को समझें जिन पर विभिन्न लूप दोहराए जाते हैं, उनकी अलग-अलग कार्यक्षमताओं, और महसूस करते हैं कि वे अलग-अलग परिदृश्यों के लिए कम या ज्यादा उपयुक्त होंगे।

इसके अलावा, इसे forEach विधि के for...in सामान्य विधि में उपयोग करने के लिए बेहतर अभ्यास माना जा सकता है, क्योंकि इसे लिखना आसान है और इसमें अधिक कार्यक्षमता है, इसलिए आप केवल इस विधि का उपयोग करने की आदत प्राप्त कर सकते हैं और मानक के लिए मानक, लेकिन आपकी कॉल।

See below that the first two loops only execute the console.log statements once, while the standard for loop executes the function as many times as specified, in this case, array.length = 6.

var arr = [];
arr[5] = 'F';

for (var index in arr) {
console.log(index);
console.log(arr[index]);
console.log(arr)
}
// 5
// 'F'
// => (6) [undefined x 5, 6]

arr.forEach(function(element, index, arr) {
console.log(index);
console.log(element);
console.log(arr);
});
// 5
// 'F'
// => Array (6) [undefined x 5, 6]

for (var index = 0; index < arr.length; index++) {
console.log(index);
console.log(arr[index]);
console.log(arr);
};
// 0
// undefined
// => Array (6) [undefined x 5, 6]

// 1
// undefined
// => Array (6) [undefined x 5, 6]

// 2
// undefined
// => Array (6) [undefined x 5, 6]

// 3
// undefined
// => Array (6) [undefined x 5, 6]

// 4
// undefined
// => Array (6) [undefined x 5, 6]

// 5
// 'F'
// => Array (6) [undefined x 5, 6]




c++ arrays standards sizeof function-parameter