Variables Scope Rules in C Programming

The scope of a variable defined the sections of a program from where a variable can be accessed. The scope of variable depends upon it's place of declaration.

There are three places where a variable can be declared in a C program:

  • Outside of all functions(including main). This type of variables are known as global variables.

  • Inside a function or inside a block of code. This type of variables are known as local variables.

  • Declared as the formal parameter in a function definition. This is similar to a local variable in scope of function's body.

Local Variables in C

Local variables in C are declared inside a function body or block of code(inside {} braces).

  • Local variables can only be accessed by other statements or expressions in same scope.

  • Local variables are not known outside of their function of declaration or block of code.

  • Local variables gets created every time control enters a function or a block of code. When control returns from function or block of code, all local variables defined within that scope gets destroyed.

  • By default, local variables contains garbage values unless we initialize it.
C Program to show use of Local Variables
#include<stdio.h>

float getAreaOfRectangle(float length, float width){
   /* local variable declaration */
   float area;
   /* area variable is only visible 
      inside getAreaOfSquare function */
   area = length*width;
   return area;
}

int main(){
   /*length and width are local 
     variables of main function */
   float length, width;
   printf("Enter length and width of rectangle\n");
   scanf("%f %f", &length, &width);
   
   printf("Area of rectangle = %f", getAreaOfRectangle(length, width));
   
   return 0;
}
Output
Enter length and width of rectangle
4.0 8.0
Area of rectangle = 32.000000

In the above program, area is local variable of getAreaOfRectangle function, Hence it cannot be accessed outside of getAreaOfRectangle function. Similarly, length and width are local variables of main function.


Global Variables in C

Global variables in C are declared outside of a function, normally it is declared before main function and after header files.

  • Global variables can be accessed form anywhere in a program. The scope of the global variables are global throughout the program.

  • Any function can access and modify value of global variables.

  • Global variables retains their value throughout the execution of entire program.

  • By default, global variables are initialized by the system when you define. Global variables of data type int, float and double gets initialized by 0 and pointer variables gets initialized by NULL.

  • We can use same name(identifiers) for local and global variables but inside a function value of local variable gets priority over global variable.
C Program to show use of Global Variables
#include<stdio.h>

/* Global variable declaration */
int area;

int main(){
   int side;
   printf("Enter side of square\n");
   scanf("%d", &side);
   /*Global Variables can be accessed from any function */
   printf("Area Before = %d\n", area);
   area = side*side;
   printf("Area After = %d", area);
   
   return 0;
}
Output
Enter side of square
5
Area Before = 0
Area After = 25

In the above program, variable area is a global variable which is defined before main function. By default, area variable gets initialized by 0.


Formal Parameters in C

Formal Parameters in C are the arguments which is used inside body of function definition. Formal parameters are treated as local variables with-in scope of that function. It gets created when control enters function and gets destroyed when control exits from function.

Any change in the formal parameters of the function have no effect on the value of actual argument. If the name of a formal parameter is same as some global variable formal parameter gets priority over global variable.

C Program to show use of Formal Parameters
#include<stdio.h>

/* Global variable declaration */
int N = 100;

void printLocalValue(int N){
    /* Inside function formal parameters and 
     * local variables get more priority over 
     * global variables 
     */
    printf("Value of N inside printLocalValue function : %d\n", N);
}

int main(){
   /*
    * main function can only access global variable N,
    * not the formal parameter of printLocalValue function
    */
    printf("Value of N inside main function : %d\n", N);
    printLocalValue(50);
   
   return 0;
}
Output
Value of N inside main function : 100
Value of N inside printLocalValue function : 50

In the above program, the formal parameter N defined inside printLocalValue function takes more priority than global variable of same name.


Scope Rules and Shadowing

When a variable in an inner scope has the same name as a variable in an outer scope, the inner variable "shadows" the outer one. This means that references to the variable name within the inner scope refer to the inner variable, not the outer one.

#include <stdio.h>

int main() {
    int x = 10; // Outer variable

    {
        int x = 20; // Inner variable shadows the outer one
        printf("Inner scope: x = %d\n", x);
    }

    // Access the outer variable
    printf("Outer scope: x = %d\n", x);

    return 0;
}
In this example, the inner variable x shadows the outer variable x within the block. The value of x inside the block is 20, while the value outside the block remains 10.


Best Practices for Variable Scope

Having reviewed the foundational aspects of variable scope in C, the following are some recommended approaches for effectively managing variable scope in one's programs:
  • Minimize Global Variables : Although global variables possess file scope and are accessible across the entire file, their utilization should be minimized whenever possible. Global variables may result in more difficult-to-maintain, debug, and comprehend code. When at all possible, pass variables as parameters to functions.

  • Keep Scope Limited : It is advisable to select variables with the most restricted scope feasible. Declare a variable within the block or function in which it is required. This practice reduces the likelihood of inadvertent variable modifications and enhances code readability.

  • Document Variable Scope : Please ensure that the remarks you provide regarding the scope of your variables are clear and concise. This is particularly important for variables that have a global or static scope. This facilitates comprehension for future developers (or oneself) regarding the intended function and significance of every variable.

  • Prefer Pass by Reference for Modification : In order to modify the value of a variable, it is preferable for a function to transmit the variable's address (via pointers) as opposed to relying on global variables. This methodology improves encapsulation and specifies which functions are authorized to modify a given variable.

  • Avoid Shadowing : It is detrimental to the code's error-prone nature and potential for confusion to utilize nested scopes that share variable names. Consider reorganizing the code to prevent shadowing or selecting a more descriptive name for a variable that shares the same name.

  • Use Static Variables with Caution : It is advisable to exercise caution when employing static variables, despite their potential utility in maintaining state between function invocations. Static variable overuse can reduce the modularity and readability of a program. Utilize them only in circumstances where their conduct is critical.

Conclusion

Variable scope is an essential principle in C programming that has a direct influence on the manner in which variables are manipulated and accessed. Developers can enhance the modularity, readability, and maintainability of their code by acquiring knowledge of static, block, function, and file scopes. Ensuring code quality and simplifying the codebase for comprehension and maintenance for both oneself and others can be achieved through the observance of best practices. These practices include minimizing the use of global variables, selecting suitable variable names, and maintaining a limited scope.