C Language
पहचानकर्ता स्कोप
खोज…
स्कोप को ब्लॉक करें
एक पहचानकर्ता के पास ब्लॉक स्कोप है यदि इसकी संबंधित घोषणा एक ब्लॉक के अंदर दिखाई देती है (फ़ंक्शन परिभाषा में पैरामीटर घोषणा लागू होती है)। स्कोप संगत ब्लॉक के अंत में समाप्त होता है।
समान पहचानकर्ता वाली कोई भी अलग-अलग इकाइयाँ एक ही गुंजाइश नहीं हो सकती हैं, लेकिन स्कोप ओवरलैप हो सकते हैं। ओवरलैपिंग स्कोप के मामले में एकमात्र दृश्यमान अंतरतम क्षेत्र में घोषित एक है।
#include <stdio.h>
void test(int bar) // bar has scope test function block
{
int foo = 5; // foo has scope test function block
{
int bar = 10; // bar has scope inner block, this overlaps with previous test:bar declaration, and it hides test:bar
printf("%d %d\n", foo, bar); // 5 10
} // end of scope for inner bar
printf("%d %d\n", foo, bar); // 5 5, here bar is test:bar
} // end of scope for test:foo and test:bar
int main(void)
{
int foo = 3; // foo has scope main function block
printf("%d\n", foo); // 3
test(5);
printf("%d\n", foo); // 3
return 0;
} // end of scope for main:foo
फंक्शन प्रोटोटाइप स्कोप
#include <stdio.h>
/* The parameter name, apple, has function prototype scope. These names
are not significant outside the prototype itself. This is demonstrated
below. */
int test_function(int apple);
int main(void)
{
int orange = 5;
orange = test_function(orange);
printf("%d\r\n", orange); //orange = 6
return 0;
}
int test_function(int fruit)
{
fruit += 1;
return fruit;
}
ध्यान दें कि यदि आपको किसी प्रोटोटाइप में एक प्रकार का नाम मिलता है, तो आप त्रुटि संदेश पा सकते हैं:
int function(struct whatever *arg);
struct whatever
{
int a;
// ...
};
int function(struct whatever *arg)
{
return arg->a;
}
GCC 6.3.0 के साथ, यह कोड (स्रोत फ़ाइल dc11.c
) dc11.c
करता है:
$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -c dc11.c
dc11.c:1:25: error: ‘struct whatever’ declared inside parameter list will not be visible outside of this definition or declaration [-Werror]
int function(struct whatever *arg);
^~~~~~~~
dc11.c:9:9: error: conflicting types for ‘function’
int function(struct whatever *arg)
^~~~~~~~
dc11.c:1:9: note: previous declaration of ‘function’ was here
int function(struct whatever *arg);
^~~~~~~~
cc1: all warnings being treated as errors
$
फ़ंक्शन की घोषणा से पहले संरचना की परिभाषा रखें, या struct whatever;
जोड़ें struct whatever;
फ़ंक्शन घोषणा से पहले एक पंक्ति के रूप में, और कोई समस्या नहीं है। आपको फ़ंक्शन प्रोटोटाइप में नए प्रकार के नाम नहीं मिलाने चाहिए क्योंकि उस प्रकार का उपयोग करने का कोई तरीका नहीं है, और इसलिए उस फ़ंक्शन को परिभाषित करने या उपयोग करने का कोई तरीका नहीं है।
फाइल स्कोप
#include <stdio.h>
/* The identifier, foo, is declared outside all blocks.
It can be used anywhere after the declaration until the end of
the translation unit. */
static int foo;
void test_function(void)
{
foo += 2;
}
int main(void)
{
foo = 1;
test_function();
printf("%d\r\n", foo); //foo = 3;
return 0;
}
कार्यक्षेत्र गुंजाइश
फंक्शन स्कोप लेबल के लिए विशेष स्कोप है। यह उनकी असामान्य संपत्ति के कारण है। संपूर्ण फ़ंक्शन के माध्यम से एक लेबल दिखाई देता है और एक ही फ़ंक्शन में किसी भी बिंदु से इसे (अनुदेश goto
label
का उपयोग करके) कूद सकता है। उपयोगी नहीं होने पर, निम्न उदाहरण बिंदु का वर्णन करता है:
#include <stdio.h>
int main(int argc,char *argv[]) {
int a = 0;
goto INSIDE;
OUTSIDE:
if (a!=0) {
int i=0;
INSIDE:
printf("a=%d\n",a);
goto OUTSIDE;
}
}
INSIDE
अंदर परिभाषित कर सकते हैं लग if
, ब्लॉक के रूप में यह मामले के लिए है i
जो गुंजाइश ब्लॉक है, लेकिन यह नहीं है। यह निर्देश goto INSIDE;
रूप में पूरे समारोह में दिखाई दे रहा है goto INSIDE;
दिखाता है। इस प्रकार एक ही फ़ंक्शन में एक ही पहचानकर्ता के साथ दो लेबल नहीं हो सकते।
एक संभावित उपयोग आवंटित रेज़र के सही जटिल क्लीनअप का एहसास करने के लिए निम्नलिखित पैटर्न है:
#include <stdlib.h>
#include <stdio.h>
void a_function(void) {
double* a = malloc(sizeof(double[34]));
if (!a) {
fprintf(stderr,"can't allocate\n");
return; /* No point in freeing a if it is null */
}
FILE* b = fopen("some_file","r");
if (!b) {
fprintf(stderr,"can't open\n");
goto CLEANUP1; /* Free a; no point in closing b */
}
/* do something reasonable */
if (error) {
fprintf(stderr,"something's wrong\n");
goto CLEANUP2; /* Free a and close b to prevent leaks */
}
/* do yet something else */
CLEANUP2:
close(b);
CLEANUP1:
free(a);
}
CLEANUP1
और CLEANUP2
जैसे लेबल विशेष पहचानकर्ता हैं जो अन्य सभी पहचानकर्ताओं से अलग व्यवहार करते हैं। वे फ़ंक्शन के अंदर हर जगह से दिखाई देते हैं, यहां तक कि उन स्थानों में भी जो लेबल वाले बयान से पहले निष्पादित किए जाते हैं, या यहां तक कि उन जगहों पर भी पहुंचा जा सकता है यदि कोई भी goto
निष्पादित नहीं होता है। ऊपरी मामले की बजाय निचले मामले में लेबल अक्सर लिखे जाते हैं।