2012-06-12 21 views
13

मैं सी भाषा में काम कर रहा हूं और पहले किसी अन्य व्यक्ति द्वारा लिखे गए कोड को संशोधित कर रहा हूं। मैं कुछ चीजों से जूझ रहा हूं और मैं जितना कर सकता हूं उतना समझने की कोशिश कर रहा हूं जितना मैं कर सकता हूं। इसलिए, जैसा कि मेरे प्रश्न में कहा गया है, फ़ंक्शन बनाते समय static inline void और void के बीच क्या अंतर है? मैं लंबे पद के लिए पहले से माफी माँगता हूं, लेकिन मैं चाहता था कि आप जान लें कि मैंने कुछ शोध किया है, लेकिन मुझे नहीं पता कि मुझे क्या मिला है।स्थिर इनलाइन शून्य और शून्य के बीच क्या अंतर है?

मैंने पाया an explanation of static कि मुझे confuses:

स्थिर विनिर्देशक का प्रतीक है कि समारोह अन्य फ़ाइलों से संदर्भित नहीं किया जा सकता; यानी, नाम लिंकर द्वारा निर्यात नहीं किया जाता है।

इसे पढ़कर, मुझे लगता है कि फ़ंक्शन को संदर्भित करने से फ़ंक्शन को संदर्भित करना अलग है? मुझे लगता है कि क्योंकि यह फ़ंक्शन किसी अन्य .c फ़ाइल से कहा जाता है। यदि ऐसा है, तो फ़ंक्शन का संदर्भ क्या है?

उसी वेबसाइट के माध्यम से, वे inline functions समझाते हैं और मुझे समझ में नहीं आता कि इसका क्या अर्थ है।

__inline कीवर्ड संकलक को फ़ंक्शन कॉल के प्रत्येक उदाहरण के लिए फ़ंक्शन परिभाषा के भीतर कोड को प्रतिस्थापित करने के लिए कहता है। हालांकि, प्रतिस्थापन केवल संकलक के विवेकाधिकार पर होता है। उदाहरण के लिए, संकलक एक फ़ंक्शन इनलाइन नहीं करता है यदि उसका पता लिया गया है या यदि यह इनलाइन के लिए बहुत बड़ा है।

हू ???

किसी भी मदद की बहुत सराहना की जाती है, और मैं एक बार फिर से बहुत लंबी पोस्ट के लिए क्षमा चाहता हूं।

निम्नलिखित file1.c में स्थित है (सामान्य नाम का उपयोग के रूप में मैं यह मायने रखता है नहीं लगता है)

COMPLEX cNoiseSample; 
CGauss(&cNoiseSample, loopbackRadio->pState); 

निम्नलिखित file2.c

static inline void CGauss(COMPLEX * pcGauss, P_OS_UNIFORM_RAND_STATE pState) 
{ 
    //code 
} 

उत्तर

12

static का अर्थ है कि इसे किसी अन्य संकलन इकाई (स्रोत फ़ाइल) से संदर्भित नहीं किया जा सकता है। "संदर्भित" का अर्थ है नाम से जाना जाता है, या अन्यथा नाम से संदर्भित किया जाता है, उदा। एक फ़ंक्शन पॉइंटर को असाइन किया गया।

inline संकलक के लिए एक संकेत है कि फ़ंक्शन का कोड उस स्थान पर इनलाइन जेनरेट किया जाना चाहिए, जिसे ब्रांडेड करने के लिए एक अलग फ़ंक्शन के रूप में जेनरेट किया गया है। यह आम तौर पर प्रदर्शन कारणों से किया जाता है। माइक्रोसॉफ्ट के उद्धरण के साथ सौदा करने के लिए:

संकलक एक समारोह इनलाइन नहीं करता है तो इसका पता लिया जाता है या अगर यह इनलाइन करने के लिए बहुत बड़ी है।

एक रेखांकित फ़ंक्शन का कोई पता नहीं है, क्योंकि यह एक अलग इकाई के रूप में मौजूद नहीं है। इसका कोड उस कोड के साथ सहजता से अंतर्निहित है जिसे इसे कहा जाता है। इसलिए, यदि आप किसी फ़ंक्शन का पता लेते हैं (उदा। एक पॉइंटर को असाइन करने के लिए) तो कंपाइलर को इसे वास्तविक फ़ंक्शन के रूप में उत्पन्न करना होगा, और इसे इनलाइन नहीं कर सकता है।

void का अर्थ है कि फ़ंक्शन कोई मान नहीं देता है।


अपने कोड नमूना को देखा, मैं, लगता था CGauss() कहीं की एक अलग परिभाषा है, जो file1.c से बुलाया जा रहा है है कि वहाँ जबकि file2.c अपनी निजी बुला रहा है संस्करण। या तो, या file1.c#include आईएन file2.c है। जो बुरा होगा।

+0

भी, एक संकल्प नियम को लागू करने के लिए 'इनलाइन' आवश्यक है जब विभिन्न संकलन इकाइयों में शामिल शीर्षलेख में फ़ंक्शन परिभाषित किया गया हो (या कम से कम यह सी ++ के मामले में है, तो इस विवरण को बिल्कुल सी में नहीं पता, मैं कल्पना करें कि यह वही होगा) – rubenvb

+0

ठीक है मुझे लगता है कि मैं @ ग्राहम-बोर्लैंड की तुलना में थोड़ा उलझन में हूं। मुझे आपको दिखाने दो क्यों: COMPLEX cNoise नमूना; CGAuss (& cNoiseSample, loopbackRadio-> pState);/* यह कोड एक .c स्रोत फ़ाइल में एक बिंदु पर और एक अलग .c स्रोत फ़ाइल में कहा जाता है, मेरे पास यह है: */स्थिर इनलाइन शून्य CGAuss (COMPLEX * पीसीगास, P_OS_UNIFORM_RAND_STATE pState)/* मैं खराब स्वरूपण के लिए क्षमा चाहता हूं टिप्पणी बॉक्स में, यह सुनिश्चित नहीं था कि यह और कैसे करें। */ – TZPike05

+0

अपना प्रश्न संपादित करें, उस कोड स्निपेट को वहां पेस्ट करें। –

6
में स्थित है

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

inline एक संकलक अनुकूलन है जो कुछ मामलों में आपके कोड को गति देता है। जब भी आप कोई फ़ंक्शन कॉल करते हैं, तो इसके साथ जुड़े कुछ ओवरहेड होते हैं। तो संकलक क्या कर सकता है, कॉपी-पेस्टिंग (लगभग) इनलाइन कोड द्वारा सभी कार्यों को एक साथ छुटकारा पाएं।

int dotproduct(int x1, int y1, int x2, int y2) { 
    return multiply(x1,x2)+multiply(y1,y2); 
} 

inline int multiply(int a, int b) { 
    return a*b; 
} 

संकलक में इस बदल जाएगी:

यहाँ इनलाइनिंग का एक उदाहरण है

int dotproduct(int x1, int y1, int x2, int y2) { 
    return x1*x2+y1*y2; 
} 

आप कल्पना होने के लिए चाहते हैं, तो आप भी dotproduct समारोह इनलाइन कर सकते हैं;)

ध्यान दें कि inline कीवर्ड केवल कुछ फ़ंक्शंस को इनलाइन करने के लिए कंपाइलर के लिए एक झुकाव है। यह वास्तव में अपने निर्णय के आधार पर ऐसा नहीं कर सकता है या नहीं।

+0

धन्यवाद @tskuzzy, इनलाइन अब बहुत अधिक समझ में आता है। – TZPike05

0

स्थिर बस मतलब यह है कि अनिवार्य रूप से समारोह सभी उद्देश्यों के लिए है और उद्देश्यों के 'अदृश्य' स्रोत फ़ाइल है कि यह में परिभाषित किया गया है के बाहर।

इनलाइन संकलक अनिवार्य रूप से स्रोत में सीधे समारोह कॉल कोड substite लिए askes प्रत्येक स्थान पर फ़ंक्शन संकलन समय (फ़ंक्शन के कोड के साथ फ़ंक्शन कॉल के प्रतिस्थापन की तरह) पर कॉल किया जाता है - हालांकि, यह होने की गारंटी नहीं है, यह केवल आपके कंपाइलर को सुझाव देता है।

यह उससे अधिक तकनीकी है और आपको एक बेहतर उत्तर पाने की संभावना है, लेकिन सरल भाषा में यह शब्द क्या है।

2

static मुख्य शब्द

एक सी समारोह स्थिर साधन को परिभाषित करना (के रूप में डॉक्स कहते हैं) है कि इस समारोह एकमात्र स्रोत से पहुँचा जा सकता फ़ाइल उस में परिभाषित किया गया है। इस भावना साधन में शब्द 'संदर्भ' या तो इस फ़ंक्शन को कॉल करना या उदाहरण के लिए फ़ंक्शन पॉइंटर लेना।

foo: 
    /* some machine code */ 
    ret 

हर बार जब आप इस फ़ंक्शन को कॉल करें, संकलक एक निर्देश सम्मिलित करता है:

इनलाइन

आम तौर पर, जब आप सी में एक समारोह के बारे में, संकलक इस कार्य के लिए मशीन कोड उत्पन्न करता है जैसे कि

call <foo> 

कॉलर के मशीन कोड में, जिसका अर्थ है "foo to foo, e xecute जो आप वहां पाते हैं और जब आप एक दूरस्थ निर्देश का सामना करते हैं, तो इस स्थान पर वापस आएं। "

इसके विपरीत, इनलाइन फ़ंक्शंस के लिए, कंपाइलर एक अलग फ़ंक्शन foo() उत्पन्न नहीं करता है, बल्कि इसके बजाय प्रत्येक कॉल साइट में फ़ंक्शन foo के लिए मशीन कोड डालें। इस कोड को निष्पादित करते समय, इसका एक ही प्रभाव होता है।

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

इसके अलावा, आप इनलाइन फ़ंक्शंस में फ़ंक्शन पॉइंटर्स नहीं ले सकते हैं, और डिबगिंग कठिन हो जाती है, क्योंकि आप आसानी से इनलाइन फ़ंक्शन पर ब्रेकपॉइंट सेट नहीं कर सकते हैं।

इसलिए, इनलाइन किए जाने वाले एक अनुकूलन विकल्प के रूप में संकलक के लिए और इस तरह के सी ++ के इनलाइन, अपने इनलाइन निर्देश, या जीसीसी के __attribute ((इनलाइन)) एक संकेत है, आप केवल संकलक दे कि इनलाइन किए जाने वाले के रूप में एक कीवर्ड का उपयोग करके छोड़ दिया है यहां एक कोशिश के लायक हो सकता है।

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