2011-04-20 14 views
21

सी (या सी पर आधारित एक भाषा), कोई खुशी से इस कथन का उपयोग कर सकता है:# वास्तव में क्या शामिल है?

#include "hello.h"; 

और voila, hello.h में प्रत्येक फ़ंक्शन और चर स्वचालित रूप से प्रयोग योग्य है।

लेकिन वास्तव में यह क्या करता है? मैंने कंपाइलर दस्तावेज़ और ट्यूटोरियल के माध्यम से देखा और ऑनलाइन खोज करने में कुछ समय बिताया, लेकिन जादुई #include कमांड के बारे में एकमात्र इंप्रेशन मैं बना सकता हूं कि यह उस पंक्ति के बजाय hello.h की सामग्री को कॉपी करता है। उस से अधिक होना चाहिए।

+2

यदि यह कोई सांत्वना है, तो प्रीप्रोसेसर कार्यान्वयन-विशिष्ट एनोटेशन भी डाल सकता है ताकि अगर डीबग जानकारी उत्पन्न हो, तो यह लाइन नंबर सही हो जाता है। यदि इसका शाब्दिक रूप से कॉपी-पेस्ट का प्रभाव पड़ा, तो डीबगर को "असली" स्रोत फ़ाइल और लाइन नंबर नहीं पता होगा। कॉपी-पेस्ट से पहले '__FILE__' और' __LINE__' को प्रतिस्थापित किया जाना चाहिए। जहां तक ​​कार्यक्रम का अर्थ है, हालांकि, कॉपी-पेस्ट यह है। –

उत्तर

21

तार्किक रूप से, वह कॉपी/पेस्ट बिल्कुल होता है। मुझे डर है कि इसके लिए और कुछ नहीं है। हालांकि, आपको ; की आवश्यकता नहीं है।

आपका विशिष्ट उदाहरण कल्पना से आच्छादित है, अनुभाग 6.10.2 स्रोत फ़ाइल शामिल किए जाने, पैरा 3:

प्रपत्र की एक पूर्व प्रसंस्करण निर्देश

# include"q-चार परिणाम"नई लाइन

" डिलीमीटर के बीच निर्दिष्ट अनुक्रम द्वारा पहचाने गए स्रोत फ़ाइल की संपूर्ण सामग्री द्वारा उस निर्देश के प्रतिस्थापन का कारण बनता है।

5

वह (प्रतिलिपि/पेस्ट) बिल्कुल #include "header.h" करता है।

ध्यान दें कि यह #include <header.h> के लिए अलग होगा या जब संकलक "header.h" फ़ाइल नहीं ढूंढ सकता है और यह इसके बजाय #include <header.h> पर प्रयास करता है।

+1

"अलग" केवल उसमें यह आमतौर पर विभिन्न स्थानों में खोज करता है और मानसिक रूप से (मानक) लाइब्रेरी हेडर से जुड़ा होता है। – delnan

+0

@ डेलनान, उन्हें बिल्कुल अलग नहीं होना चाहिए - सभी खोजों को spec के अनुसार "कार्यान्वयन-परिभाषित" तरीके से किया जाता है। अंतर यह है कि '' 'फॉर्म' <> 'फॉर्म पर वापस आ जाता है अगर यह काम नहीं करता है। @ पीपीजी पूरी तरह से सही है। –

+0

इसके अलावा "अलग" क्योंकि ''thing.h' नाम की फ़ाइल की आवश्यकता नहीं है, जब आप '#' शामिल करते हैं। उदाहरण के लिए जीसीसी में – pmg

0

वास्तव में नहीं, नहीं। कंपाइलर मूल फ़ाइल डिस्क्रिप्टर को एक स्टैक पर सहेजता है और #include डी फ़ाइल खोलता है; जब यह उस फ़ाइल के अंत तक पहुंच जाता है, तो यह इसे बंद कर देता है और मूल फ़ाइल डिस्क्रिप्टर पर वापस आ जाता है। इस तरह, यह लगभग मनमाने ढंग से #include डी फ़ाइलों को घोंसला कर सकता है।

+1

कंपाइलर पास उदाहरण के बारे में कुछ भी नहीं जानता है, क्योंकि यह प्रीप्रोसेसर पास है। – fazo

+0

@fazo: ज्यादातर मामलों में, भेद अर्थहीन है। अगर आपको किसी कारण से पैडेंट्री की ज़रूरत है, तो मैं कंपाइलर्स की अपूर्ण सूची खोद सकता हूं और क्या वे प्रीप्रोसेसरों का उपयोग कर सकते हैं या नहीं। – geekosaur

0

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

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