Global variables are variables that can be accessed by any function anywhere. In general, you may have heard that you should never use global variables. More correctly, you should not use global variables unless there is a very good reason, and even then it is useful to restrict the scope.
In contrast with global variables, temporary variables that are used to solve a problem should be declared as local: the memory is allocated for these, and when they go out of scope, the memory is no longer allocated.
Another issue is that beginning programmers tend to places far too many temporary variables in classes or data structures. If a variable (a single occurrence or an array of either primitive data types or records) describes the state of the object being described, then it should be a field in the associated record (or member variable in the associated class); however, if that variable is simply being used to solve a problem, even if it is an array, it should be a local variable.
For example, algorithms such as Dijkstra's algorithm requires multiple arrays. Some of these describe the graph itself, and therefore must be associated with the record describing the graph; however, some arrays are used for the algorithm to track which vertices have been visited. These arrays are only initialized in the routine performing Dijkstra's algorithm, and their content is meaningless once the algorithm exits. Consequently, they should be local variables, either by having a local variable being
Suppose, however, you have a very large array and there are functions that require this in memory. Now we have a problem, because if that array is declared local to the array, as in
void f() { int array[N] = {1, 2, 3, ..., N}; // ... }
we have the following issue: this array must be loaded from the data segment onto the stack. This is a Θ(N) operation that must be performed with each function call. If the data, however, is always going to be the same, it might be better to declare this data as a global array of constants:
int const array[N] = {1, 2, 3, ..., N};
Now, the array can always be accessed by a given function call and its entries cannot be changed.
One significant issue with global variables is the principle of modularity: this requires the separation of the programs into modules, each of which contains only that which is necessary to achieve the desired functionality. One consequence is that data should not be accessible, even in principle, by packages not associated with its use.
The solution C had for this is the concept of a static global variable. Here, the word static indicates that a variable is local to the file in which it is declared.
For example, suppose an array is declared as static inside a file containing two functions main(...) and init(...). In this case, that array could only be accessed by these two functions, while other global variables could be accessible in other files.
Now, such an array is shared by all functions within a file. If it is declared const, none of those functions can modify the entries. If it is not constant and the entries are being modified by the functions, we may have to take additional steps to ensure that multiple functions, running in parallel, do not corrupt the data.