c - स्रोत फ़ाइलों के बीच चर साझा करने के लिए मैं बाहरी का उपयोग कैसे करूं?




global-variables extern (10)

मुझे पता है कि सी में वैश्विक चर के पास कभी-कभी extern कीवर्ड होता है। एक extern चर क्या है? घोषणा की तरह क्या है? इसका दायरा क्या है?

यह स्रोत फ़ाइलों में चर साझा करने से संबंधित है, लेकिन यह ठीक से कैसे काम करता है? मैं extern कहां उपयोग करूं?


लेकिन यह ठीक से कैसे काम करता है?

चलो देखते हैं कि कैसे जीसीसी 4.8 ईएलएफ इसे लागू करता है

main.c :

#include <stdio.h>

int not_extern_int = 1;
extern int extern_int;

void main() {
    printf("%d\n", not_extern_int);
    printf("%d\n", extern_int);
}

संकलन और decompile:

gcc -c main.c
readelf -s main.o

आउटपुट में शामिल हैं:

Num:    Value          Size Type    Bind   Vis      Ndx Name
 9: 0000000000000000     4 OBJECT  GLOBAL DEFAULT    3 not_extern_int
12: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND extern_int

सिस्टम वी एबीआई अपडेट ईएलएफ स्पेक "प्रतीक तालिका" अध्याय बताता है:

SHN_UNDEF यह खंड तालिका अनुक्रमणिका का अर्थ है कि प्रतीक अपरिभाषित है। जब लिंक संपादक इस ऑब्जेक्ट फ़ाइल को दूसरे के साथ जोड़ता है जो संकेतित प्रतीक को परिभाषित करता है, तो इस फ़ाइल के प्रतीक के संदर्भ वास्तविक परिभाषा से जुड़े होंगे।

जो मूल रूप से सी मानक मानक चर को देता है।

अब से, यह अंतिम कार्यक्रम बनाने के लिए लिंकर का काम है, लेकिन extern जानकारी को स्रोत कोड से ऑब्जेक्ट फ़ाइल में पहले ही निकाला जा चुका है।


एक extern चर एक परिवर्तनीय (एक सुधार के लिए एसबीआई के लिए धन्यवाद) है जो एक अन्य अनुवाद इकाई में परिभाषित किया गया है। इसका मतलब है कि चर के लिए भंडारण किसी अन्य फ़ाइल में आवंटित किया गया है।

मान लें कि आपके पास दो .c test2.c और test2.c । यदि आप वैश्विक वैरिएबल int test1_var; को परिभाषित int test1_var; test2.c आप test2.c में इस चर को एक्सेस करना चाहते हैं, आपको extern int test1_var; का उपयोग extern int test1_var; test2.c

पूरा नमूना:

$ cat test1.c 
int test1_var = 5;
$ cat test2.c
#include <stdio.h>

extern int test1_var;

int main(void) {
    printf("test1_var = %d\n", test1_var);
    return 0;
}
$ gcc test1.c test2.c -o test
$ ./test
test1_var = 5

बाहरी कंप्रेसर को आपको विश्वास करने के लिए कहता है कि इस चर के लिए स्मृति कहीं और घोषित की गई है, इसलिए यह स्मृति आवंटित / जांचने की कोशिश नहीं करता है।

इसलिए, आप एक फ़ाइल को संकलित कर सकते हैं जिसमें बाहरी का संदर्भ है, लेकिन अगर आप उस स्मृति को कहीं भी घोषित नहीं करते हैं तो आप लिंक नहीं कर सकते हैं।

वैश्विक चर और पुस्तकालयों के लिए उपयोगी, लेकिन खतरनाक है क्योंकि लिंकर चेक टाइप नहीं करता है।


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


मैं एक बाहरी चर के बारे में सोचना चाहता हूं कि आप संकलक को बनाते हैं।

एक बाहरी का सामना करते समय, कंपाइलर केवल अपना प्रकार ढूंढ सकता है, न कि जहां यह "रहता है", इसलिए यह संदर्भ को हल नहीं कर सकता है।

आप इसे बता रहे हैं, "मेरा विश्वास करो। लिंक समय पर यह संदर्भ हल करने योग्य होगा।"


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

#include<stdio.h>
extern int a;
main(){
       printf("The value of a is <%d>\n",a);
}

example1.c

int a = 5;

अब जब आप निम्न आदेशों का उपयोग करके दो फ़ाइलों को एक साथ संकलित करते हैं:

चरण 1) cc -o ex example.c example1.c चरण 2) ./ ex

आपको निम्न आउटपुट मिलता है: एक का मान <5> है


extern is used so one first.c file can have full access to a global parameter in another second.c file.

The extern can be declared in the first.c file or in any of the header files first.c includes.


extern simply means a variable is defined elsewhere (ie, in another file).


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

यह भी दर्शाता है कि आप किसी भी फ़ाइल में बाहरी कीवर्ड का उपयोग करके घोषित वैरिएबल का उपयोग कर सकते हैं, हालांकि इसे अन्य फाइल में घोषित / परिभाषित किया गया है।


First off, the extern keyword is not used for defining a variable; rather it is used for declaring a variable. I can say extern is a storage class, not a data type.

extern is used to let other C files or external components know this variable is already defined somewhere. Example: if you are building a library, no need to define global variable mandatorily somewhere in library itself. The library will be compiled directly, but while linking the file, it checks for the definition.







extern