Scope rules in C

Scope of an identifier is the part of the program where the identifier may directly be accessible. In C, all identifiers are lexically (or statically) scoped. C scope rules can be covered under following two categories.

There are basically 4 scope rules:

Scope Meaning
File Scope Scope of a Identifier starts at the beginning of the file and ends at the end of the file. It refers to only those Identifiers that are declared outside of all functions. The Identifiers of File scope are visible all over the file Identifiers having file scope are global
Block Scope Scope of a Identifier begins at opening of the block / ‘{‘ and ends at the end of the block / ‘}’. Identifiers with block scope are local to their block
Function prototype Scope Identifiers declared in function prototype are visible within the prototype
Function scope Function scope begins at the opening of the function and ends with the closing of it. Function scope is applicable to labels only. A label declared is used as a target to goto statement and both goto and label statement must be in same function

Now we will discuss each scope rule with examples.
Global Scope: Can be accessed anywhere in a program.



filter_none

edit
close

play_arrow

link
brightness_4
code

// filename: file1.c
int a;
int main(void)
{
   a = 2;
}

chevron_right


filter_none

edit
close

play_arrow

link
brightness_4
code

// filename: file2.c
// When this file is linked with file1.c, functions 
// of this file can access a
extern int a;
int myfun()
{
   a = 2;
}

chevron_right


To restrict access to the current file only, global variables can be marked as static.

Block Scope: A Block is a set of statements enclosed within left and right braces ({ and } respectively). Blocks may be nested in C (a block may contain other blocks inside it). A variable declared in a block is accessible in the block and all inner blocks of that block, but not accessible outside the block.

What if the inner block itself has one variable with the same name?
If an inner block declares a variable with the same name as the variable declared by the outer block, then the visibility of the outer block variable ends at the pint of the declaration by inner block.

filter_none

edit
close

play_arrow

link
brightness_4
code

#include<stdio.h>
int main()
{
  {
      int x = 10, y  = 20;
      {
          // The outer block contains declaration of x and y, so 
          // following statement is valid and prints 10 and 20
          printf("x = %d, y = %d\n", x, y);
          {
              // y is declared again, so outer block y is not accessible 
              // in this block
              int y = 40;
     
              x++;  // Changes the outer block variable x to 11
              y++;  // Changes this block's variable y to 41
       
              printf("x = %d, y = %d\n", x, y);
          }
  
          // This statement accesses only outer block's variables
          printf("x = %d, y = %d\n", x, y);
      }
  }
  return 0;
}

chevron_right


Output:

x = 10, y = 20
x = 11, y = 41
x = 11, y = 20

What about functions and parameters passed to functions?
A function itself is a block. Parameters and other local variables of a function follow the same block scope rules.

Can variables of the block be accessed in another subsequent block?*
No, a variable declared in a block can only be accessed inside the block and all inner blocks of this block. For example, the following program produces a compiler error.

filter_none

edit
close

play_arrow

link
brightness_4
code

int main()
{
  {
      int x = 10;
  }
  {
      printf("%d", x);  // Error: x is not accessible here
  }
  return 0;
}

chevron_right


Error:

prog.c: In function 'main':
prog.c:8:15: error: 'x' undeclared (first use in this function)
  printf("%d", x); // Error: x is not accessible here
               ^
prog.c:8:15: note: each undeclared identifier is 
reported only once for each function it appears in

As an exercise, predict the output of the following program.

filter_none

edit
close

play_arrow

link
brightness_4
code

#include<stdio.h>
int main()
{
  int x = 1, y = 2, z = 3;
  printf(" x = %d, y = %d, z = %d \n", x, y, z);
  {
       int x = 10;
       float y = 20;
       printf(" x = %d, y = %f, z = %d \n", x, y, z);
       {
             int z = 100;
             printf(" x = %d, y = %f, z = %d \n", x, y, z);
       }
  }
  return 0;
}

chevron_right


Output:

 x = 1, y = 2, z = 3 
 x = 10, y = 20.000000, z = 3 
 x = 10, y = 20.000000, z = 100 

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.



My Personal Notes arrow_drop_up



Article Tags :
Practice Tags :


40


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.