Course Content
Programming in C
About Lesson

In the program we saw in the previous section to input text, reverse and print it, we declared a few variables including len, line, etc. within main, these are local to main and no other function can have direct access to them. The same is true for variables declared in other functions.

Each local variable in a function comes into existence when the function is called and disappears when the function is exited. These local variables are called automatic variables. As automatic variables come and go with function invocation, they do not retain their values between function calls and must be explicitly set upon each entry, else they will contain garbage value by default.

We can also define variables that are external to all functions and can be accessed by name by any function. Because external variables are globally accessible, they can be used instead of argument lists to communicate data between functions. Furthermore, because external variables remain in existence permanently, they retain their values even after the functions that set them have returned.

An external variables must be defined exactly once, outside of any function; this sets aside storage for it. The variable must also be declared in each function that wants to access it; this states the type of the variable. The declaration may be an explicit extern statement or implicit from context.

Let’s re-write the program from the previous section (to input text and reverse it), using external variables.

#include <stdio.h>

#define MAX_LEN 80

int length;
char line[MAX_LEN];
char rev_line[MAX_LEN];

int get_line();
void reverse();

int main()
{
    extern int length;
    extern char line[];
    extern char rev_line[];

    while ((length= get_line()) > 0) {
      reverse();
      printf("Reverse of %s is %s.\n", line, rev_line);
    }   
    return 0;
}

int get_line()
{
    int c, i;
    extern char line[];
   
    for(i = 0; i < MAX_LEN - 1 && (c = getchar()) != EOF && c != '\n'; i++) {
        line[i] = c;  
    }   
    line[i] = '\0';
    return i;
}

void reverse()
{
    int i;
    extern int length;
    extern char line[];
    extern char rev_line[];

    for (i = 0; i < length; i++) {
        rev_line[i] = line[length - i - 1]; 
    }   
    rev_line[i] = '\0';
}

To terminate the program, press ^d (ctrl + d) at the beginning of a line (after pressing enter and without typing any characters). When you press ^d with an empty buffer, getchar() will return with zero bytes, and this gets interpreted as EOF (end of file).
In the above program, we define three external variables: length, line and rev_line. Syntactically, external definitions are just like the definitions of local variables, but since they occur outside of functions, the variables are external.
Before a function can use an external variable, the name of the variable must be known to the function. One way to do this is to write an extern declaration in the function. If the definition of an external variable occurs in the source file before its use in a particular function (as is the case in out example above), then there is no need for an extern declaration in the function. The extern declaration of length, line and rev_line are thus redundant. It’s a common practice to place all the external variables definitions at the beginning of the source file and omit all extern declarations.
In a program with several source files, if a external variable is defined in file1 and used in file2 and file3, then extern declarations are needed in file2 and file3 to connect the occurrences of the variable. The usual practice is to collect external declarations of variables and functions in a separate file, called a header file, that is included by #include at the front of each source file. The suffix .h is conventional for header names. For example, the functions of the standard library are declared in “stdio.h”.
Also, let’s clarify the difference between variable definition and declaration. Definition refers to the place where the variable is created or assigned storage. Declaration refers to the place where the nature of the variable is stated but no storage is allocated.
Looking at external variables, it might seem that by defining everything as extern, we may simplify the code. But external variables are always there even when you don’t want them. Relying too much on external variables is fraught with peril since it leads to programs whose data connections are not at all obvious. The program we saw above is inferior to the program we wrote in the last section because of these reasons along with the fact that it destroys the generality of the two functions by wiring into them names of the variables they manipulate.

Scroll to Top