C Programming Scope

Last modified by Microchip on 2023/11/09 09:06

Scope
Scope is a region of the program where a defined variable is valid, and outside of this region that variable cannot be accessed.

Parameters

Any variables declared as a parameter to a function only exist within the context of the function. In other words, the rest of the program does not have any ability to directly read or modify parameter variables aside from passing values to them in a function call. Because of this, parameter names may be the same as another variable name declared outside of the function or in another function. When the function does something with n from the example here, the n that it uses is the one in the parameter list, effectively making the "global" n inaccessible from within the function. This can be avoided by giving the parameter a different name from the "global" variable. Ordinarily, a function can access "global" variables just like any other part of the program.

1 int n;
2 long int factorial(int n){}

Different functions may use the same parameter names, but the function will only use its own parameter by that name.

Parameters

Variables Declared Within a Function

Just like with function parameters, if a variable is declared within the function body, it will be local to the function. So, if a variable of the same name is declared globally, code within the function can only access the local variable, whereas code outside the function can only access the global variable. Also, just like function parameters, the same name may be used for variable declarations in different functions. Each function will only use its version of the variable by that name.

1 int x, y, z;
2  
3 void foo(int n)
4 {
5     int a;
6             // The n referes to the function parameter n
7     a += n;  // The a refers to the a declared locally
8              // within the function body
9 }

 The next piece of code will generate an error since a may not be accessed outside of the function where it was declared.

1 int x;
2 int foo(int n)
3 {
4     int a = 2;
5     return (a += n);
6 }
7 int main(void)
8 {
9     x = foo(5);
10     x = a;
11 }

Global vs Local Variables

In the following example:

  • x can be seen by everybody
  • foo's local parameter is y
  • foo's local variable is z
  • foo cannot see main a
  • foo can see x
  • main's local variable is a
  • main cannot see foo's y or z
  • main can see x
1 int x = 5;      
2  
3 int foo(int y)
4 {               
5   int z = 1;    
6   return (x + y + z);     
7 }
8  
9 int main(void)
10 {
11   int a = 2;    
12   x = foo(a);   
13   a = foo(x);   
14 }

A locally defined identifier takes precedence over a globally defined identifier.

Overloading

#define Within a Function

1  #define x 2
2  
3  void test(void)
4  {
5      #define x 5
6      printf("%d\n", x);
7  }
8  
9  void main(void)
10 {
11     printf("%d\n", x);
12     test();
13 }

 Running this code will result in the following output in the UART1 IO window:

 5
5

Why? Because the closest #define for x above its use defines x = 5. The order of the code's execution doesn't matter here. The value is determined purely by its position within the source file's text. When using #define, just think of your source code as an ordinary linear text file. The label's value is valid from the line of the file where it is defined all the way to the end of the file unless it is redefined along the way.

Historical Note

C originally defined functions like this:

1 int maximum(x, y)
2 int x, int y
3 {
4   return ((x >= y) ? x : y);
5 }

DO NOT use the old method! Use the new one only:

1 int maximum(int x, int y)
2 {
3   return ((x >= y) ? x : y);
4 }