2016-07-25 5 views
6

मैं निम्नलिखित सी कोड C99 और/या C11 मानक (रों) का पालन करता है कि क्या जानना चाहते हैं:के लिए सूचक का उपयोग करके एक समारोह के तर्कों के माध्यम से बार-बार दोहराना पहले एक

void foo(int bar0, int bar1, int bar2) { 
    int *bars = &bar0; 

    printf("0: %d\n1: %d\n2: %d\n", bars[0], bars[1], bars[2]); 
} 

int main(int argc, char **argv) { 
    foo(8, 32, 4); 

    return 0; 
} 

यह कोड स्निपेट compiles

0: 8
1: 32
2: 4

और जब दृश्य स्टूडियो 2013 और प्रिंट का उपयोग कर चलाता है के रूप में उम्मीद 0
+1

क्या आप अपनी जिज्ञासा को पूरा करने के लिए कह रहे हैं, या क्या आपको कोई समस्या है जो आपको लगता है कि यह हल हो जाएगा? – StoryTeller

+0

जिज्ञासा से बाहर, क्योंकि विविध तर्क इस तकनीक का उपयोग अपने तर्कों को फिर से करने के लिए करते हैं। –

उत्तर

11

नहीं, कहीं भी पास।

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

कुछ और स्पष्टता जोड़ने के लिए, यहां तक ​​कि इस बात की कोई गारंटी नहीं है कि पारित होने वाले तर्क स्मृति (जैसे, ढेर) में संग्रहीत हैं। वे हार्डवेयर रजिस्टरों का भी उपयोग कर सकते हैं, जब भी लागू होते हैं), कुछ या संचालन को तेज़ बनाने के लिए सभी पैरामीटर के लिए। उदाहरण के लिए,

  • PowerPC

    PowerPC वास्तुकला इतनी अधिकांश कार्यों को एकल स्तर कॉल के लिए रजिस्टर में सभी तर्क पारित कर सकते हैं रजिस्टरों की एक बड़ी संख्या है। [...]

  • MIPS

    32 बिट MIPS के लिए सबसे अधिक इस्तेमाल किया बुला सम्मेलन O32 ABI जो रजिस्टरों में एक समारोह के लिए पहले चार तर्क गुजरता है $a0 - $a3; बाद के तर्क ढेर पर पारित कर दिए जाते हैं। [...]

  • X86

    86 आर्किटेक्चर कई अलग अलग बुला सम्मेलनों के साथ प्रयोग किया जाता है। आर्किटेक्चरल रजिस्ट्रारों की छोटी संख्या के कारण, x86 कॉलिंग सम्मेलन ज्यादातर स्टैक पर तर्क देते हैं, जबकि रिटर्न वैल्यू (या इसके लिए पॉइंटर) एक रजिस्टर में पास किया जाता है।

और इतने पर। full wiki article here देखें।

तो, आपके मामले में, bars[0] एक वैध पहुँच है, लेकिन bars[1] और bars[2] मान्य हैं कि क्या, अंतर्निहित पर्यावरण (मंच/संकलक) पर निर्भर करता है, पूरी तरह से। आप जिस व्यवहार की अपेक्षा कर रहे हैं उस पर भरोसा न करें।

कहा कि, बस, nitpick करने के मामले में आप तर्क का उपयोग करने के इरादा नहीं है (किसी भी अगर) main() को पारित कर दिया, तो आप बस हस्ताक्षर int main(void) { को कम कर सकते हैं।

+0

+1, लेकिन शायद इसे आधुनिक आर्किटेक्चर पर जोड़ना चाहिए, पहले फ़ंक्शन पैरामीटर स्मृति में संग्रहीत नहीं हैं बल्कि हार्डवेयर रजिस्टरों के माध्यम से पारित किए जाते हैं। और शायद यह भी कि यह संकलक नहीं है जो निर्णय लेता है, लेकिन मंच एपीआई। –

+0

@ जेन्सगस्टेड सर, उस मोर्चे पर थोड़ा और जानकारी जोड़ा। अब कोई बेहतर है? –

5

कोई मानक इसका समर्थन नहीं करता है। यह बेहद शरारती है।

ऐरे इंडेक्सिंग और पॉइंटर अंकगणितीय केवल सरणी के लिए मान्य है। (नोट एक छोटा सा अपवाद:। आप एक सूचक एक सरणी या एक अदिश अतीत पढ़ सकते हैं, लेकिन आप सम्मान नहीं कर सकते हैं यह)

7

नहीं, यह किसी भी प्रकाशित मानक का पालन नहीं करता है। तर्क और स्थानीय चर कैसे संग्रहीत किए जाते हैं, और कहां, कंपाइलर पर है। एक कंपाइलर में क्या काम हो सकता है, दूसरे में या एक ही कंपाइलर के एक अलग संस्करण पर भी काम नहीं कर सकता है।

सी विनिर्देशन में एक ढेर का भी उल्लेख नहीं है, यह निर्दिष्ट करता है कि यह स्कोपिंग नियम हैं।

+0

वैराडिक फ़ंक्शंस मानक का हिस्सा भी प्रतीत होता है - va_start, va_end मानक लाइब्रेरी का हिस्सा हैं, और यह वही है जो ये मैक्रोज़ कर रहे हैं - स्टैक पैरामीटर पर जा रहे हैं। – MichaelMoser

+3

@MichaelMoser हां, लेकिन उन मैक्रोज़ को कैसे कार्यान्वित किया जाता है मानक में नहीं है। और एक ढेर होने के लिए एक सी संकलक (विशेष रूप से क्योंकि यह सी विनिर्देशन में नहीं है) के लिए एक आवश्यकता नहीं है, यह केवल सुविधाजनक कार्यान्वयन विस्तार है। –

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