2012-06-15 14 views
20

में स्थैतिक और बाहरी वैश्विक चर, मैंने 2 परियोजनाएं बनाईं, सी में पहला और सी ++ में दूसरा, दोनों एक ही व्यवहार के साथ काम करते हैं।सी और सी ++

सी परियोजना:

header.h

int varGlobal=7; 

main.c

#include <stdio.h> 
#include <stdlib.h> 
#include "header.h" 

void function(int i) 
{ 
    static int a=0; 
    a++; 
    int t=i; 
    i=varGlobal; 
    varGlobal=t; 
    printf("Call #%d:\ni=%d\nvarGlobal=%d\n\n",a,i,varGlobal,t); 
} 

int main() { 
    function(4); 
    function(6); 
    function(12); 
    return 0; 
} 

सी ++ परियोजना:

header.h

int varGlobal=7; 

main.cpp

#include <iostream> 
#include "header.h" 
using namespace std; 

void function(int i) 
{ 
    static int a=0; 
    int t=i; 
    a++; 
    i=varGlobal; 
    varGlobal=t; 
    cout<<"Call #"<<a<<":"<<endl<<"i="<<i<<endl<<"varGlobal="<<varGlobal<<endl<<endl; 
} 

int main() { 
    function(4); 
    function(6); 
    function(12); 
    return 0; 
} 

मैंने पढ़ा है कि वैश्विक चर सी में डिफ़ॉल्ट रूप से निर्वासन डिफ़ॉल्ट रूप से और सी में और स्थिर हैं ++; तो सी ++ कोड क्यों काम करता है?

मेरा मतलब है int varGlobal = 7;स्थिर int varGlobal = 7 के समान है; और यदि यह स्थैतिक है तो इसका उपयोग केवल उस फ़ाइल में किया जा सकता है जिसे घोषित किया गया था, है ना?

+0

सबसे पहले ध्यान दें कि 'बस include' कॉपी-सामग्री को चिपकाता है। तो इस तरह के एक फ़ाइल उदाहरण के लिए, इसे सरल बनाने के लिए हटा दिया जाना चाहिए। –

उत्तर

63

वैश्विक चर extern और static डिफ़ॉल्ट रूप से सी और सी ++ पर नहीं हैं। जब आप static के रूप में एक चर घोषित करते हैं, तो आप इसे वर्तमान स्रोत फ़ाइल में प्रतिबंधित कर रहे हैं। आप extern के रूप में यह घोषणा करते हैं, तो आप कह रहे हैं कि चर मौजूद है, लेकिन कहीं और घोषणा की जाती है, और यदि आप (extern कीवर्ड के बिना) इसे कहीं और की घोषणा की जरूरत नहीं है आप एक लिंक त्रुटि (नहीं मिला प्रतीक) मिल जाएगा। आपको लगता है कि शीर्ष लेख सहित अधिक स्रोत फ़ाइलें है जब

आपका कोड टूट जाएगा, लिंक समय पर आप varGlobal करने के लिए कई संदर्भ होगा। यदि आप इसे static के रूप में घोषित करते हैं, तो यह एकाधिक स्रोतों (मेरा मतलब है, यह संकलित और लिंक करेगा) के साथ काम करेगा, लेकिन प्रत्येक स्रोत का अपना varGlobal होगा।

आप C++ क्या कर सकते हैं कि आप नहीं कर सकते सी में, चर const के रूप में इस तरह, शीर्षक पर घोषित करने के लिए है,: पर चीजों को तोड़ने के बिना

const int varGlobal = 7; 

और कई स्रोतों में शामिल हैं, लिंक समय विचार स्थिरांक के लिए पुरानी सी शैली #define को प्रतिस्थापित करना है।

आप एक वैश्विक चर कई स्रोतों पर दिखाई दे रहा है और न const जरूरत है, यह extern हैडर पर के रूप में ऐलान करते हैं और निर्वासन keywork बिना फिर से यह घोषणा, इस बार एक स्रोत फ़ाइल पर,:

हेडर द्वारा शामिल एक से अधिक फ़ाइलों:

extern int varGlobal; 

अपने स्रोत फ़ाइलों में से एक में:

int varGlobal = 7; 
+3

जैसा कि मैंने अभी पाया है, वहां * सी * सी ++ के बीच एक अंतर है, लेकिन यह केवल ** const ** ऑब्जेक्ट्स पर लागू होता है: http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp? विषय =% 2Fcom.ibm.xlcpp8l.doc% 2 भाषा% 2Fref% 2Fconst_cv_qualifier.htm –

+0

यदि आप चीजों को हेडर में डालने जा रहे हैं, तो कुछ कंपाइलर/लिंकर्स परिभाषित प्रतीकों को गुणा करने के बारे में शिकायत करेंगे। उदाहरण: 'const int varGlobal = 7;' क्योंकि आप इसे 'const' घोषित कर रहे हैं, इसे वैश्विक स्थिरता के रूप में माना जा सकता है, लेकिन कुछ कंपाइलर स्मार्ट नहीं हैं। काम करता है, हमेशा, हेडर फ़ाइल में चीजों को 'स्थैतिक const'' घोषित करना है, जैसे: 'static const int varGlobal = 7; 'इस तरह से अगर संकलक बेवकूफ है, तो यह बाहरी को प्रतीक नहीं जोड़ देगा प्रतीक तालिका और लिंकर कभी गुणा परिभाषित प्रतीकों को कभी नहीं देख पाएंगे। – steveha

+0

@steveha "स्थिर कॉन्स" के रूप में निरंतर घोषित करने से हेडर को शामिल करने वाली फ़ाइलों पर कष्टप्रद चेतावनियां पैदा होंगी, लेकिन निरंतर उपयोग नहीं करें (बेशक, आपके कंपाइलर और चेतावनियों के आधार पर सक्षम)। – fbafelipe

6

जब आप #include हेडर करते हैं, तो यह ठीक है जैसे आप कोड को स्रोत फ़ाइल में डाल देते हैं। दोनों मामलों में varGlobal चर स्रोत में परिभाषित किया गया है, इसलिए इससे कोई फर्क नहीं पड़ता कि यह कैसे घोषित किया गया है।

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

+3

इसके अलावा, ओपी इस धारणा में गलत है कि विश्व स्तर पर घोषित चर डिफ़ॉल्ट रूप से C++ में स्थिर हैं। उनके पास बाहरी * लिंकेज * है, जैसा कि सी में है। वैश्विक चर के पास स्थिर और अवधि * सी और सी ++ में है, इसलिए यह आसानी से भ्रमित हो सकता है। – nos

+0

तो नियम * .c एक * .cpp फ़ाइलों के लिए appllies लेकिन * .h फ़ाइलों के लिए नहीं? धन्यवाद! – Cristi

+0

मैं गलत था ... धन्यवाद! – Cristi