Coding With Fun
Home Docker Django Node.js Articles Python pip guide FAQ Policy

Take you through several types of C-language automatic variables


Jun 01, 2021 Article blog


Table of contents


Let's first look at what automatic 自动变量 are, and variables that fall into the auto-storage category have automatic storage periods, block scopes, and no links. B y default, any variable declared in a block or function header falls into the automatic storage category. In general, local variables that are not specified are automatic variables.

The keyword auto

To express your intentions more clearly (for example, to indicate an intentional override of an external variable definition, or to emphasize not changing the variable to another storage category), you can explicitly use the keyword auto as follows:

int main(void)
{
  auto int plox;

The keyword auto is the storage category descriptor. auto of the auto keyword in C++ is completely different, and if you're writing C/C++ program, it's a good idea not to use auto as a storage category descriptor.

块作用域 and 无链接 mean that the variable can only be accessed through the variable name in the block where the variable definition is located (of course, arguments are used to pass the value and address of the variable to another function, but this is an indirect method). Another function can use a variable with the same name, but the variable is another variable stored in different memory locations.

Having an automatic storage period for a variable means that the variable exists when the program enters the block where the variable is declared, and the variable disappears when the program exits the block. The memory position previously occupied by the variable is now available for other purposes.

The case of fast nesting

Let's take a look at nested blocks. The variables declared in the block are limited to the use of the block and the block it contains.

int loop(int n)
{
     int m;          // m in scope
     scanf("%d", &m);
     {
          int i;    // both m and i in scope
          for (i = m; i < n; i++)
               puts("i is local to a sub-blockn");
     }
     return m;     // m in scope, i gone
}

In the code above, i is only visible in the inner block. I f i is used before or after the inner block, the compiler will report an error. T ypically, this feature is not used when designing programs. H owever, if the variable is only available for use by the block, it is convenient to define the variable near the block. T his allows you to record the meaning of a variable near where it is used. I n addition, such variables only consume memory when used. Variables n and m are defined in the function header and outer block, respectively, and their scope is the entire function and exists from the time the function is called until the end of the function.

What if the variable declared in the inner block has the same name as the variable in the outer block? T he inner block hides the definition of the outer block. B ut after leaving the inner block, the scope of the outer block variable returns to its original scope. The program hiding.c demonstrates this process.

// hiding.c -- variables in blocks
#include <stdio.h>
int main()
{
    int x = 30;      // original x


    printf("x in outer block: %d at %pn", x, &x);
    {
        int x = 77;  // new x, hides first x
        printf("x in inner block: %d at %pn", x, &x);
    }
    printf("x in outer block: %d at %pn", x, &x);
    while (x++ < 33) // original x
    {
        int x = 100; // new x, hides first x
        x++;
        printf("x in while loop: %d at %pn", x, &x);
    }
    printf("x in outer block: %d at %pn", x, &x);


    return 0;
}

Here is the output of the program:

x in outer block: 30 at 0x7fff5fbff8c8
x in inner block: 77 at 0x7fff5fbff8c4
x in outer block: 30 at 0x7fff5fbff8c8
x in while loop: 101 at 0x7fff5fbff8c0
x in while loop: 101 at 0x7fff5fbff8c0
x in while loop: 101 at 0x7fff5fbff8c0
x in outer block: 34 at 0x7fff5fbff8c8

First, the program creates the variable x and initializes it to 30, as shown in the printf() statement 1. T hen, a new variable x is defined and set to 77, as shown in the printf() statement 2. D epending on the address displayed, the new variable hides the original x T he 3rd printf() statement, located behind the first inner block, shows the value of the original x indicating that the original x has neither disappeared nor changed. Perhaps the most difficult thing for the program to understand is while循环

The original x is used in the test conditions of the while循环

while(x++ < 33)

In this loop, the program creates the third x variable, which is defined only in the while loop. T herefore, when executing x++ in the loop body, the increment of 101 is the new x and then the printf() statement shows the value. A t the end of each iteration, the new x variable disappears. T he test condition of the loop then uses and increments the original x enters the loop body again, and creates a new x again. I n this example, this x was created and destroyed three times. Note that the loop must increment x in the test condition because if x increment x in the loop body, the increment is x created in the loop body, not the original x used in the test condition.

The compiler we use does not reuse the memory occupied by x in the inner block when creating x in the while while循环体 but some compilers do.

The purpose of the program example is not to encourage the reader to write similar code (it is not difficult to come up with other variable names according to C naming rules), but to explain the specifics of defining variables in the inner layer.

A block without braces

A C99 attribute mentioned earlier is a block, even if you don't use {} as part of a loop or if statement. M ore completely, the entire loop is a sub-block of the block in which it is located, and the loop body is a sub-block of the entire loop block. S imilarly, an if statement is a block, and the child statement associated with it is a child of an if statement. T hese rules affect the declared variables and the scope of those variables. The program forc99.c demonstrates the use of this feature in for循环

// forc99.c -- new C99 block rules
#include <stdio.h>
int main()
{
    int n = 8;


    printf("   Initially, n = %d at %pn", n, &n);
    for (int n = 1; n < 3; n++)
        printf("      loop 1: n = %d at %pn", n, &n);
    printf("After loop 1, n = %d at %pn", n, &n);
    for (int n = 1; n < 3; n++)
    {
        printf(" loop 2 index n = %d at %pn", n, &n);
        int n = 6;
        printf("      loop 2: n = %d at %pn", n, &n);
        n++;
    }
    printf("After loop 2, n = %d at %pn", n, &n);


    return 0;
}

Assuming that the compiler supports this new feature of C语言 the output of the program is as follows:

Initially, n = 8 at 0x7fff5fbff8c8
loop 1: n = 1 at 0x7fff5fbff8c4
loop 1: n = 2 at 0x7fff5fbff8c4
After loop 1, n = 8 at 0x7fff5fbff8c8
loop 2 index n = 1 at 0x7fff5fbff8c0
loop 2: n = 6 at 0x7fff5fbff8bc
loop 2 index n = 2 at 0x7fff5fbff8c0
loop 2: n = 6 at 0x7fff5fbff8bc
After loop 2, n = 8 at 0x7fff5fbff8c8

One thing to note:

Some compilers that support C99 and C11 do not support these scope rules for C99/C11 (Microsoft Visual Studio 2012 is one of them). S ome compilations provide the option to activate these rules. For example, when writing this book, gcc supports many of the features of C99 by default, but activates the features used in Listing 12.2 with the –std=c99 option:

gcc --std=c99 forc99.c

Similarly, gcc or clang use –std=c1x or -std=c11 options to support C11特性

Program forc99.c n declared in the header of the 1st for loop, which scopes to the end of the loop and hides the original n However, after leaving the loop, the original n works again.

The n declared in the second for loop header is the index of the loop, hiding the original n T hen, an n is declared in the loop body, hiding the index n A t the end of a round of iterations, n declared in the loop body disappears, and the loop header is tested using index n W hen the entire loop ends, the original n works again. A gain, remind the reader that there is no need to use the same variable name in the program. If used, the case of each variable is described above.

The initialization of the automatic variable

The automatic variable is not initialized unless it is explicitly initialized. Consider the following statement:

int main(void)
{
  int repid;
  int tents = 5;

tents variable is initialized to 5, but the value of the repid variable is any value, if any, that previously occupied the space allocated to repid and don't expect it to be 0. Automatic variables can be initialized with non-constantexpression, provided that the variables used have been defined earlier:

int main(void)
{
  int repid;
  int tents = 5;

The above is about the C语言 of several automatic variables explained, interested students can look at the C language related tutorials

C tutorial: https://www.w3cschool.cn/c/