c - programing - सी में समारोह परिभाषा




सी में "स्थैतिक" का क्या अर्थ है? (12)

मैंने सी कोड में विभिन्न स्थानों में इस्तेमाल शब्द शब्द देखा है; क्या यह सी # में स्थिर कार्य / वर्ग की तरह है (जहां कार्यान्वयन वस्तुओं पर साझा किया जाता है)?


  1. फ़ंक्शन के अंदर एक स्थिर चर इनवॉक्शंस के बीच अपना मान रखता है।
  2. एक स्थैतिक वैश्विक परिवर्तनीय या फ़ंक्शन केवल उस फ़ाइल में "देखा" है जिसे घोषित किया गया है

(1) यदि आप नौसिखिया हैं तो अधिक विदेशी विषय है, तो यहां एक उदाहरण दिया गया है:

#include <stdio.h>

void foo()
{
    int a = 10;
    static int sa = 10;

    a += 5;
    sa += 5;

    printf("a = %d, sa = %d\n", a, sa);
}


int main()
{
    int i;

    for (i = 0; i < 10; ++i)
        foo();
}

यह प्रिंट:

a = 15, sa = 15
a = 15, sa = 20
a = 15, sa = 25
a = 15, sa = 30
a = 15, sa = 35
a = 15, sa = 40
a = 15, sa = 45
a = 15, sa = 50
a = 15, sa = 55
a = 15, sa = 60

यह उन मामलों के लिए उपयोगी है जहां फ़ंक्शन को कुछ राज्यों को इनवोकेशन के बीच रखने की आवश्यकता होती है, और आप वैश्विक चर का उपयोग नहीं करना चाहते हैं। सावधान रहें, हालांकि, इस सुविधा को बहुत कम इस्तेमाल किया जाना चाहिए - यह आपके कोड को थ्रेड-सुरक्षित और समझने में कठोर नहीं बनाता है।

(2) व्यापक रूप से "अभिगम नियंत्रण" सुविधा के रूप में उपयोग किया जाता है। यदि आपके पास कुछ कार्यक्षमता लागू करने वाली .c फ़ाइल है, तो यह आमतौर पर उपयोगकर्ताओं को केवल कुछ "सार्वजनिक" फ़ंक्शंस का खुलासा करती है। इसके बाकी कार्यों को static बनाया जाना चाहिए, ताकि उपयोगकर्ता उन्हें एक्सेस नहीं कर पाए। यह encapsulation है, एक अच्छा अभ्यास है।

Wikipedia उद्धरण:

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

अधिक जानकारी के लिए here और here देखें।

और अपने दूसरे प्रश्न का उत्तर देने के लिए, यह सी # की तरह नहीं है।

सी ++ में, हालांकि, static वर्ग वर्ग गुणों (उसी वर्ग की सभी वस्तुओं के बीच साझा) और विधियों को परिभाषित करने के लिए भी प्रयोग किया जाता है। सी में कोई कक्षा नहीं है, इसलिए यह सुविधा अप्रासंगिक है।


एक स्थिर परिवर्तनीय मान अलग-अलग फ़ंक्शन कॉल और स्कॉप्स के बीच बनी रहती है स्थानीय ब्लॉक तक सीमित है एक स्थिर var हमेशा मूल्य 0 के साथ प्रारंभ होता है


निर्भर करता है:

int foo()
{
   static int x;
   return ++x;
}

समारोह 1, 2, 3, आदि लौटाएगा --- परिवर्तनीय ढेर पर नहीं है।

एसी:

static int foo()
{
}

इसका मतलब है कि इस फ़ंक्शन में केवल इस फ़ाइल में गुंजाइश है। तो एसी और बीसी में अलग foo() एस हो सकता है, और foo साझा वस्तुओं से अवगत नहीं है। तो यदि आपने एसी में foo परिभाषित किया है तो आप इसे bc या किसी अन्य स्थानों से एक्सेस नहीं कर पाएंगे।

अधिकांश सी पुस्तकालयों में सभी "निजी" कार्य स्थिर होते हैं और अधिकांश "सार्वजनिक" नहीं होते हैं।


मुझे एक पुराने प्रश्न का उत्तर देने से नफरत है, लेकिन मुझे नहीं लगता कि किसी ने उल्लेख किया है कि के एंड आर ने "सी प्रोग्रामिंग भाषा" की धारा ए 4.1 में इसे कैसे समझाया।

संक्षेप में, स्थैतिक शब्द दो अर्थों के साथ प्रयोग किया जाता है:

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

पीटर वान डेर लिंडेन इन विशेषज्ञों को "विशेषज्ञ सी प्रोग्रामिंग" में देते हैं:

  • एक समारोह के अंदर, कॉल के बीच अपना मूल्य बरकरार रखता है।
  • फ़ंक्शन स्तर पर, केवल इस फ़ाइल में दिखाई देता है।

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

यदि आप वैश्विक परिवर्तनीय स्थिर घोषित करते हैं, तो इसका दायरा उस फ़ाइल के भीतर प्रतिबंधित होगा जिसमें आपने इसे घोषित किया था। यह एक नियमित वैश्विक से थोड़ा सुरक्षित है जिसे आपके पूरे कार्यक्रम में पढ़ और संशोधित किया जा सकता है।


यह ध्यान रखना महत्वपूर्ण है कि कार्यों में स्थैतिक चर उस समारोह में पहली प्रविष्टि में प्रारंभ हो जाते हैं और उनकी कॉल समाप्त होने के बाद भी बने रहते हैं; रिकर्सिव फ़ंक्शंस के मामले में स्थिर चर केवल एक बार शुरू होता है और सभी रिकर्सिव कॉल पर भी रहता है और फ़ंक्शन की कॉल समाप्त होने के बाद भी।

यदि चर के फ़ंक्शन के बाहर चर बनाया गया है, तो इसका अर्थ यह है कि प्रोग्रामर केवल स्रोत-फ़ाइल में चर का उपयोग करने में सक्षम है, चर को घोषित कर दिया गया है।


यहां एक और उपयोग शामिल नहीं है, और यह किसी फ़ंक्शन के तर्क के रूप में सरणी प्रकार की घोषणा के हिस्से के रूप में है:

int someFunction(char arg[static 10])
{
    ...
}

इस संदर्भ में, यह निर्दिष्ट करता है कि इस फ़ंक्शन को पास किए गए तर्क कम से कम 10 तत्वों के साथ प्रकार char की सरणी होनी चाहिए। अधिक जानकारी के लिए here मेरा प्रश्न देखें।


लोग कहते हैं कि सी में 'स्थैतिक' के दो अर्थ हैं। मैं इसे देखने का एक वैकल्पिक तरीका प्रदान करता हूं जो इसे एक अर्थ देता है:

  • आइटम को 'स्थैतिक' लागू करना उस आइटम को दो गुणों के लिए मजबूर करता है: (ए) यह वर्तमान दायरे के बाहर दिखाई नहीं दे रहा है; (बी) यह लगातार है।

ऐसा लगता है कि दो अर्थ होने का कारण यह है कि, सी में, प्रत्येक आइटम जिसे 'स्थैतिक' लागू किया जा सकता है, में पहले से ही इन दो गुणों में से एक है , ऐसा लगता है कि उस विशेष उपयोग में केवल दूसरे शामिल हैं।

उदाहरण के लिए, चर पर विचार करें। कार्यों के बाहर घोषित वैरिएबल पहले से ही दृढ़ता (डेटा सेगमेंट में) है, इसलिए 'स्थैतिक' लागू करने से उन्हें केवल मौजूदा दायरे (संकलन इकाई) के बाहर दिखाई नहीं दे सकता है। इसके विपरीत, कार्यों के अंदर घोषित चर के पास पहले से ही मौजूदा दायरे (फ़ंक्शन) के बाहर गैर-दृश्यता है, इसलिए 'स्थिर' लागू करने से केवल उन्हें लगातार बना दिया जा सकता है।

कार्यों के लिए 'स्थैतिक' लागू करना वैश्विक चर के लिए इसे लागू करने जैसा है - कोड आवश्यक रूप से लगातार (भाषा में कम से कम) है, इसलिए केवल दृश्यता को बदला जा सकता है।

नोट: ये टिप्पणियां केवल सी ++ में लागू होती हैं, कक्षा विधियों के लिए 'स्थैतिक' लागू करना वास्तव में कीवर्ड को एक अलग अर्थ दे रहा है। इसी प्रकार सी 99 सरणी-तर्क एक्सटेंशन के लिए।


संक्षिप्त उत्तर ... यह निर्भर करता है।

  1. स्टेटिक परिभाषित स्थानीय चर फ़ंक्शन कॉल के बीच अपना मान नहीं खोते हैं। दूसरे शब्दों में वे वैश्विक चर हैं, लेकिन स्थानीय फ़ंक्शन में शामिल हैं जिन्हें वे परिभाषित करते हैं।

  2. स्टेटिक ग्लोबल वैरिएबल उन सी फाइल के बाहर दिखाई नहीं दे रहे हैं जिन्हें वे परिभाषित करते हैं।

  3. स्टेटिक फ़ंक्शंस उन सी फ़ाइल के बाहर दिखाई नहीं दे रहे हैं जिन्हें वे परिभाषित करते हैं।


सी में स्थिर चर कार्यक्रम के जीवनकाल है।

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

उदाहरण के लिए:

void function()
{
    static int var = 1;
    var++;
    printf("%d", var);
}

int main()
{
    function(); // Call 1
    function(); // Call 2
}

उपर्युक्त प्रोग्राम में, var सेगमेंट में var संग्रहित किया जाता है। इसका जीवनकाल पूरे सी कार्यक्रम है।

फ़ंक्शन कॉल 1 के बाद, var बन जाता है 2. फ़ंक्शन कॉल 2 के बाद, var 3 बन जाता है।

कार्य कॉल के बीच var का मूल्य नष्ट नहीं होता है।

यदि var स्थिर और स्थानीय चर के बीच var था, तो यह सी प्रोग्राम में स्टैक सेगमेंट में संग्रहीत किया जाएगा। चूंकि फ़ंक्शन रिटर्न के बाद फ़ंक्शन का स्टैक फ्रेम नष्ट हो जाता है, इसलिए var का मान भी नष्ट हो जाता है।

प्रारंभिक स्थैतिक चर सी प्रोग्राम के डेटा सेगमेंट में संग्रहीत होते हैं जबकि अनियमित लोग बीएसएस सेगमेंट में संग्रहीत होते हैं।

स्थैतिक के बारे में एक और जानकारी: यदि एक चर वैश्विक और स्थैतिक है, तो उसके पास सी प्रोग्राम का जीवन समय है, लेकिन इसमें फ़ाइल का दायरा है। यह केवल उस फ़ाइल में दिखाई देता है।

इसे आजमाने के लिए:

file1.c

static int x;

int main()
{
    printf("Accessing in same file%d", x):
}

file2.c

    extern int x;
    func()
    {
        printf("accessing in different file %d",x); // Not allowed, x has the file scope of file1.c
    }

run gcc -c file1.c

gcc -c file2.c

अब उनका उपयोग करके लिंक करने का प्रयास करें:

gcc -o output file1.o file2.o

यह एक लिंकर त्रुटि देगा क्योंकि x में file1.c का फ़ाइल दायरा है और लिंकर file2.c में उपयोग किए गए चर x के संदर्भ को हल करने में सक्षम नहीं होगा।

संदर्भ:

  1. http://en.wikipedia.org/wiki/Translation_unit_(programming)
  2. http://en.wikipedia.org/wiki/Call_stack

स्टेटिक चर के पास उनके दायरे से बाहर होने के बाद भी उनके मूल्य को संरक्षित करने की एक संपत्ति होती है! इसलिए, स्थिर चर उनके पिछले दायरे में अपने पिछले मूल्य को संरक्षित करते हैं और नए दायरे में फिर से शुरू नहीं किए जाते हैं।

1. प्रोग्राम चल रहा है, जबकि एक स्थिर int चर स्मृति में रहता है। एक सामान्य या ऑटो वैरिएबल नष्ट हो जाता है जब एक फ़ंक्शन कॉल जहां चर घोषित किया गया था।

2. स्टेटिक वेरिएबल्स को डेटा सेगमेंट में स्मृति आवंटित किया जाता है, न कि स्टैक सेगमेंट।

3. स्थिर चर (जैसे वैश्विक चर) को 0 के रूप में प्रारंभ किया गया है यदि स्पष्ट रूप से प्रारंभ नहीं किया गया है। उदाहरण के लिए नीचे दिए गए कार्यक्रम में, एक्स का मान 0 के रूप में मुद्रित किया गया है, जबकि वाई का मान कुछ कचरा है। अधिक जानकारी के लिए इसे देखें।

#include <stdio.h>

int main()
   {
    static int x;
    int y;
    printf("%d \n %d", x, y);
   }

static मतलब विभिन्न संदर्भों में अलग-अलग चीजें हैं।

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

    void foo ()
    {
    static int i = 0;
    printf("%d", i); i++
    }
    
  2. स्थैतिक का एक अन्य उपयोग तब होता है जब आप किसी .c फ़ाइल में कोई फ़ंक्शन या ग्लोबल वैरिएबल लागू करते हैं, लेकिन यह नहीं चाहते कि फ़ाइल द्वारा उत्पन्न .obj बाहर उसका प्रतीक दिखाई दे। जैसे

    static void foo() { ... }
    




static