2010-08-15 16 views
6

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

int foo(matrix *A, int colnum, int rownum){ 
static int whichColumn; 
static int *v; //vector of length A->nrows 
    if (column != whichColumn){ 
    memset(v,0,size); 
    whichColumn = which; 
    } 
    //do other things 
} 

फ़ंक्शन प्रत्येक कॉलम के लिए एक बार एन बार कहा जाता है। क्या यह स्थैतिक चर "पुनः सेटिंग" का एक उचित तरीका है? क्या स्थैतिक चर को रीसेट करने के अन्य सामान्य मूर्ख-प्रमाण तरीके हैं? उदाहरण के लिए, मैं यह सुनिश्चित करना चाहता हूं कि यदि कॉल संभवतः विभिन्न आयामों के साथ एक नए मैट्रिक्स के साथ बनाया गया है तो वेक्टर वी का आकार बदल दिया गया है और शून्य हो गया है। ऐसा लगता है कि फ़ंक्शन को एक नल पॉइंटर के साथ कॉल करने का सबसे आसान तरीका हो सकता है:

int foo(matrix *A, int colnum, int rownum){ 
static int whichColumn; 
static int *v; //vector of length A->nrows 
    if (A == NULL){ 
    FREE(v); 
    whichColumn = 0; 
    } 
    //do other things 
} 
+2

स्थिर/वैश्विक चर का प्रयोग न करें के रूप में कोई भी नहीं है। इसके बजाय फ़ंक्शन को एक पूर्णांक में एक पॉइंटर पास करें जिसे कॉलर कॉल में राज्य को संरक्षित रखने के लिए बनाए रखता है। –

+0

मुझे अभी भी एक ही समस्या है Ihre मुझे अपने स्थिर चर को रीसेट करना था, लेकिन केवल मेरे टेस्ट कोड में। मेरा हैक इनपुट पॉइंटर्स को पूर्ण करने के लिए सेट करना था, उस के लिए func में जांचें, फिर वैरिएबल को उचित रूप से रीसेट करें - प्रभावी रूप से ध्वज के रूप में मौजूदा पैरामीटर में एक नल मान का उपयोग करके। थोड़ा सुगंधित लेकिन यह काम करता है। – bph

+0

स्थैतिक सदस्य चर के साथ एक वर्ग शायद आपका आदर्श समाधान होगा, लेकिन सी (नो ओओपी) के साथ शायद एक स्थैतिक संरचना शायद निकटतम सुरुचिपूर्ण समाधान है। – bph

उत्तर

0

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

+1

फांसी एक आवरण वर्ग लिखें चर के साथ अपनी सबसे मजबूत समाधान नहीं - यह एक छोटे से जोखिम भरा लग रहा है? सी में? – Beta

+0

ओह, कैसे एक स्ट्रक्चर + सहायक समारोह के बारे में? –

+0

धन्यवाद जेसी, मैंने टीओ दृष्टिकोण के एक संकर का उपयोग किया क्योंकि मेरी टिप्पणी बोरेलिड को इंगित करती है। "रीसेट" अभी भी फ़ंक्शन द्वारा बाहर विवरण छिपाने के लिए प्रबंधित किया जाता है। मुझे सी ++ नहीं पता, इसलिए रैपर वर्ग ओओटीक है। – Sue

3

इसके बजाय एक idempotent प्रारंभकर्ता फ़ंक्शन और वैश्विक चर का उपयोग करें।

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

int foo; 
int *m = NULL; 

static void InitVars() { 
    foo = 0; 
    if (m != NULL) { 
     free(m); 
    } 
    m = malloc(sizeof(int)*5); 
    memset(m, 0, sizeof(int)*5); 
} 

अपने प्रारंभकर्ता वास्तव में idempotent है, तो आप इसे फिर से चर रीसेट करने के लिए कह सकते हैं।

आप तो जरूरत इस पूर्ण रूप से अपने नाम से जाना है, तो तरह का उपयोग __attribute__((constructor)) (जीसीसी के लिए):

static void InitVars __attribute__((constructor))(); 

हालांकि, अगर आप ध्यान दें कि यदि आप ऐसा करने की जरूरत है, तो आप in- का उपयोग कर पर पुनर्विचार करना चाहिए फ़ंक्शन static चर और इसके बजाय पास किए गए ताजा लोगों का उपयोग करें जो लौटाए/लिखे गए हैं और बाद में संबंधित कॉलों को पास कर दिए गए हैं।

+0

हाय जवाब के लिए धन्यवाद जल्दी होगा सोच भी नहीं सकते। मैंने सलाह का पालन करने का फैसला किया और एक स्थिर चर के रूप में * v का उपयोग नहीं किया- इसके बजाए केवल statitc चर के रूप में कॉलम का उपयोग करें। v अब नीचे जेसी द्वारा अनुशंसित संरचना का हिस्सा है। गुजरना (कॉलम = -1) स्टेटिक वैरिएबल को रीसेट करता है और वर्क वेक्टर को फिर से परिभाषित करता है। फिर यह हर बार उचित रूप से अद्यतन किया जाता है (कॉलम! = कौन सा कॉलम)। आपका अन्य सुझाव उपयोगी लगता है और मैं इसके बारे में सीखूंगा। एक बार फिर धन्यवाद। एसएम – Sue

+0

हम्म - सुनिश्चित करें कि विश्व के उन चारों ओर – bph

0

एक दृष्टिकोण जिसे मैंने सी + मॉड्यूल में आयात किया था, एक क्लास रैपर के साथ पूरे मॉड्यूल को घेरना था, और कार्यों के बाहर विशिष्ट रूप से नामित "वैश्विक" varaibles के साथ सभी स्थैतिक चर को प्रतिस्थापित करना था। मुझे कई स्रोत फ़ाइलों से जुड़े परियोजनाओं के लिए समान प्रभाव प्राप्त करने का कोई अच्छा तरीका नहीं पता है, हालांकि मैं जानना चाहता हूं कि कोई मौजूद है या नहीं। मेरे पास सी में कुछ एम्बेडेड सिस्टम कोड है, जिसे मैं वीएस2005 में कुछ सी ++ रैपर जोड़कर अनुकरण करता हूं। उदाहरण के लिए, मेरे पास I/O रजिस्टरों को परिभाषित किया गया है ताकि TX1CON = 0x5C जैसे कुछ; IOMAP (0x251) जैसे कुछ में अनुवाद करेगा .P = 0x5C; आईओएमएपी एक ऐसी संपत्ति है जो हार्डवेयर-सिमुलेशन प्रोग्राम में "0x251 को संबोधित करने के लिए 0x5C लिखें" भेजती है। यह दृष्टिकोण अच्छी तरह से काम करता है, लेकिन मैं एक साफ रीसेट नहीं कर सकता। कोई विचार?

+0

इसके साथ समस्या यह है कि आप एक पूरे समूह के साथ समाप्त होते हैं और अधिक फ़ंक्शन == कोड ब्लोट। इसके अलावा आप केवल सीढ़ी को जिम्मेदारी को दबा रहे हैं जो अंततः आपको 'ईश्वर' कार्य विरोधी पैटर्न के लिए ले जाता है। विशेष परिदृश्य मैं VS2005 में सी ++ रैपर के साथ वर्णित में, कोड ब्लोट केवल एक सिमुलेशन संदर्भ में उत्पन्न हुई: मैं वहाँ एक स्पष्ट 'साफ़' इस के लिए एक गैर OOP भाषा – bph

+0

@Hiett के लिए समाधान नहीं लगता। चूंकि वास्तविक प्रणाली 128K ROM और 4K रैम, और सिमुलेशन वातावरण था रैम gigs था, और के बाद से वास्तविक प्रणाली शायद के रूप में तेजी से सिमुलेशन वातावरण के रूप में भाग गया "कच्चे कोड" 1% से कम है, मेरी चिंता का विषय एक ऐसे में कोड लिख रहा था सिमुलेशन संदर्भ में दक्षता के संबंध में, असली प्रणाली पर कुशल होने के तरीके के रूप में। अन्य परिस्थितियों में अन्य आवश्यकताएं होंगी। – supercat

0

एक ऐसा दृष्टिकोण जो कभी-कभी सहायक हो सकता है यदि किसी को "रीसेट" विधि की आवश्यकता होती है जो किसी अज्ञात संख्या में फ़ंक्शंस या मॉड्यूल को हिट कर सकती है, उसमें वैश्विक काउंटर होना चाहिए कि रीसेट विधि कितनी बार बुलाया गया है, और उसके बाद प्रत्येक

 
extern unsigned long global_reset_count; 

void do_something(int whatever) 
{ 
    static ... this, that, the other, etc. ...; 
    static unsigned long my_reset_count; 

    if (my_reset_count != global_reset_count) 
    { 
    my_reset_count = global_reset_count; 
    ... initialize this, that, the other, etc ... 
    } 
} 

कुछ बहु सूत्रण संदर्भों में, अगर स्थैतिक चर का प्रारंभ कुछ वैश्विक चर पर निर्भर हो सकता है, एक एक "जबकि" के साथ बदलने के लिए "अगर" इच्छा हो सकती है;: समारोह या मॉड्यूल कोड की तरह शामिल ऐसी स्थिति में; इस तरह के मामले में स्मृति बाधाओं की भी आवश्यकता हो सकती है, हालांकि ऑपरेटिंग वातावरण के आधार पर सटीक आवश्यकताएं अलग-अलग होंगी।

इसके अलावा

, एक वैकल्पिक पैटर्न है कि एम्बेडेड सिस्टम के भीतर उपयोगी हो सकता है एक modules_initialized वैश्विक चर जो वैश्विक रीसेट करने की विधि द्वारा 0 पर सेट हो जाता है के लिए हो सकता है, और उसके बाद की तरह कुछ के साथ प्रत्येक मॉड्यूल शुरुआत:

 
    if (!atomic_bit_test_and_set32(&modules_initialized, FOOBOZZ_MODULE_ID)) 
    { 
    ... Initialize module FOOBOZZ ... 
    } 

यह आवश्यकता होगी वहाँ कोई और अधिक 32 से मॉड्यूल आईडी के होने पर की आवश्यकता होगी कि वे विशिष्ट किसी भी तरह आवंटित किया है, लेकिन कुछ सिस्टम बहुत अच्छी तरह से है कि संभाल कर सकते हैं। उदाहरण के लिए, एक लिंकर किसी को किसी अन्य स्थान से स्वतंत्र पता स्थान के पते 0-31 से "डेटा सेक्शन" परिभाषित करने की अनुमति दे सकता है; यदि प्रत्येक मॉड्यूल उस पता स्थान के भीतर एकल-बाइट चर घोषित करता है, तो लिंकर उन चर के लिए उचित पते उत्पन्न कर सकता है।

int foo(matrix *A = NULL, int colnum = 0, int rownum = 0) 
{ 
    static int whichColumn; 
    static int *v; //vector of length A->nrows 

    if (A == NULL){ 
    FREE(v); 
    whichColumn = 0; 
    } 
    //do other things 
} 

आप वास्तव में सिर्फ है:

0

आप इस तरह से अपने कार्य का निर्माण कर सकता है कि अगर आप इसे शून्य मानकों के साथ कहते हैं, तो यह अपने आंतरिक स्थैतिक चर

यहाँ रीसेट कर देगा एक उदाहरण है इस तरह रीसेट करने के लिए समारोह कॉल करने के लिए:

foo(); // internal values would then be reset 

सुनिश्चित करें कि कार्य करने के लिए अपने सभी मापदंडों है मूलभूत मूल्यों, अगर उदाहरण के लिए आप एक वैकल्पिक, तो मा पारित ke यकीन है कि यह = बढ़ावा :: डिफ़ॉल्ट मान

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