C Language                
            Zakres identyfikatora
        
        
            
    Szukaj…
Zablokuj zakres
Identyfikator ma zasięg bloku, jeśli odpowiadająca mu deklaracja pojawia się w bloku (obowiązuje deklaracja parametru w definicji funkcji). Zakres kończy się na końcu odpowiedniego bloku.
Żadne różne podmioty o tym samym identyfikatorze nie mogą mieć tego samego zakresu, ale zakresy mogą się nakładać. W przypadku nakładających się zakresów jedynym widocznym jest ten zadeklarowany w najbardziej wewnętrznym zakresie.
#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
Funkcja Prototyp Zakres
#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;
}
Pamiętaj, że po wprowadzeniu nazwy typu w prototypie pojawiają się zagadkowe komunikaty o błędach:
int function(struct whatever *arg);
struct whatever
{
    int a;
    // ...
};
int function(struct whatever *arg)
{
    return arg->a;
}
 W przypadku GCC 6.3.0 ten kod (plik źródłowy dc11.c ) tworzy: 
$ 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
$
 Umieść definicję struktury przed deklaracją funkcji lub dodaj struct whatever; jako wiersz przed deklaracją funkcji i nie ma problemu. Nie należy wprowadzać nowych nazw typów w prototypie funkcji, ponieważ nie ma sposobu na użycie tego typu, a zatem nie ma możliwości zdefiniowania lub użycia tej funkcji. 
Zakres pliku
#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;
}
Zakres funkcji
 Zakres funkcji jest specjalnym zakresem dla etykiet . Wynika to z ich niezwykłej właściwości. Etykieta jest widoczna przez całą zdefiniowaną funkcję i można do niej przeskoczyć (używając instrukcji goto label ) z dowolnego punktu tej samej funkcji. Chociaż nie jest to przydatne, poniższy przykład ilustruje tę kwestię: 
#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 może wydawać się zdefiniowane wewnątrz bloku if , tak jak w przypadku i który zakres jest blokiem, ale tak nie jest. Jest widoczny w całej funkcji jako instrukcja goto INSIDE; ilustruje. Dlatego w jednej funkcji nie mogą być dwie etykiety o tym samym identyfikatorze. 
Możliwym zastosowaniem jest następujący wzorzec do realizacji poprawnych złożonych porządków przydzielonych zasobów:
#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);
}
 Etykiety takie jak CLEANUP1 i CLEANUP2 są specjalnymi identyfikatorami, które zachowują się inaczej niż wszystkie inne identyfikatory. Są one widoczne zewsząd w obrębie funkcji, nawet w miejscach, które są wykonywane przed instrukcją z etykietą, lub nawet w miejscach, do których nigdy nie można byłoby dotrzeć, gdyby żadne z goto zostało wykonane. Etykiety są często pisane małymi, a nie dużymi literami.