Summary of storage categories, links and memory management

Storage category, link and memory management

1. Storage category and scope

C language contains 4 storage types, see the following table:

feature Automatic storage type Register storage type Static storage type External storage type
Keyword auto register static external
Stored in RAM CPU register RAM RAM
Default initial value Junk value Junk value 0 or blank 0 or blank
Scope Confined to blocks Confined to blocks Confined to blocks Global
Life cycle Block Block Exists between functions Exists between functions

    Block refers to a group of statements written in left and right curly braces: "{} ". Local variables are variables declared in the block.

The difference between local variables and global variables:

  • Local variables are variables declared inside a block or function. The scope of local variables is limited to the block or function. If local variables are not initialized, they will contain garbage data.

  • Global variables are variables declared before all blocks and functions. Global variables are valid for all functions declared after it. Global variables are initialized with default values, such as 0.

Scope

The scope describes the area in the program where the identifier can be accessed. The scope of a C variable can be block scope, function scope, function prototype scope, or file scope.

  • Block scope A
    block is an area of ​​code enclosed in curly braces. For example, the entire function body is a block, and any compound statement in the function is also a block. Variables defined in a block have a block scope, and the visible range of a block scope variable is from the definition to the end of the block containing the definition. In addition, although the formal parameters of a function are declared before the opening brace of the function, they also have a block scope and belong to the block of the function body.

  • Function scope
    Function scope (function scope) is only used for tags of goto statements. This means that even if a label appears in the inner block of a function for the first time, its scope extends to the entire function. If the same label is used in two blocks, it will be confusing. The function scope of the label prevents this from happening.

  • Function prototype scope The
    function prototype scope is used for the parameter names (variable names) in the function prototype, as shown below:
    int mighty(int mouse, double large); The
    scope of the function prototype scope is from the form The parameter definition ends at the end of the prototype declaration. This means that the compiler only cares about the type of the parameter in the function prototype, and the parameter name (if any) usually doesn't matter. Moreover, even if there are formal parameter names, they do not have to match the formal parameter names in the function definition. Only in variable-length arrays, formal parameter names are useful:
    void use_a_VLA(int n, int m, ar[n][m]);
    The name declared in the function prototype must be used in square brackets.

  • File scope
    The definition of variables is outside the function and has file scope. A variable with file scope is visible from its definition to the end of the file where the definition is located.

2. Link

    C variables have three link attributes: external link, internal link or no link.
    Variables with block scope, function scope, or function prototype scope are unlinked variables. This means that these variables are private to the block, function or prototype in which they are defined. Variables with file scope can be external links or internal links. External link variables can be used in multi-file programs, and internal link variables can only be used in one translation unit.
     Detailed link

3. Storage period

    The scope and link describe the visibility of the identifier. The storage period describes the lifetime of the objects accessed through these identifiers.
    C objects have four storage periods: static storage period, thread storage period, automatic storage period, and dynamic allocation storage period.
    If the object has a static storage duration, it will always exist during the execution of the program. File scope variables have a static storage period. Note that for file scope variables, the keyword static indicates the link attribute, not the storage period . The file scope variable declared as static has internal linkage. But whether it is an internal link or an external link, all file scope variables have a static storage period.
    Thread storage period is used for concurrent programming, and program execution can be divided into multiple threads. Objects with thread storage period exist from the time they are declared to the end of the thread. When an object is declared with the keyword _Thread_local, each thread gets a private copy of the variable.
    Variables at block scope usually have automatic storage duration. When the program enters the block where these variables are defined, memory is allocated for these variables; when the block is exited, the memory just allocated for the variables is released. This approach is equivalent to treating the memory occupied by automatic variables as a reusable work area or temporary storage area. For example, after a function call ends, the memory occupied by its variables can be used to store the variables of the next called function. Variable-length arrays are slightly different, and their storage period is from the declaration to the end of the block, not from the beginning of the block to the end of the block.

4. Independent dynamic variables

    Variables belonging to the automatic storage category have automatic storage duration, block scope, and no link. By default, any variable declared in a block or function header belongs to the automatic storage category.
    Variables with automatic storage period means that the variables exist when the program enters the block where the variable is declared, and the variables disappear when the program exits the block. The memory location originally occupied by the variable can now be used for other purposes.

Static variable Automatic variable Register variable
All variables declared outside the code block Variables defined inside the code block Variables modified with register
Store in static memory Stored in the heap and stack Stored in register
Created before the program runs, and exists during the entire run until the end of the program Control flow is created when entering the code block, and destroyed when leaving The creation and destruction time is the same as the automatic variable

5. Block-scope static variables

    A static variable sounds like an immutable variable. In fact, static means that the variable stays in place in memory, not that its value does not change.
    Variables with file scope automatically have (and must be) static storage duration.
    You can create local variables with static storage duration and block scope. These variables have the same scope as automatic variables, but these variables will not disappear after the program leaves the function in which they are located. In other words, this variable has block scope, no link, but has a static storage period. The computer records their values ​​between multiple function calls. In the block (provide block scope and no link), declare this kind of variable with storage class specifier static (provide static storage period)

6. Static variables of external links

    Externally linked static variables have file scope, external linkage, and static storage period. This category is sometimes called an external storage class, and variables belonging to this category are called external variables. Putting the defining declaration of variables outside all functions creates external variables. Of course, in order to point out that the function uses external variables, you can use the keyword extern to declare it again in the function. If an external variable used by a source code file is defined in another source code file, you must use extern to declare the variable in that file.
As follows:

int Errupt;        /* 外部定义的变量 */
double Up[100];      /* 外部定义的数组 */
extern char Coal;     /* 如果Coal被定义在另一个文件,则必须这样声明 */
void next(void);
int main(void)
{
    
    
    extern int Errupt;   /* 可选的声明*/
    extern double Up[];  /* 可选的声明*/
    ...
}
void next(void)
{
    
    
    ...
}

    Note that when you declare the Up array in main() (this is an optional declaration) you don't need to specify the array size, because the first declaration has already provided the array size information. The two extern declarations in main() can be completely omitted, because external variables have file scope, so Errupt and Up are visible from the declaration to the end of the file. They appear there only to illustrate that the main() function uses these two variables.

7. Random function

Need to include header files:

#include <stdlib.h>

    The rand() function generates integers in the specified order, so each time the above statement is executed, the same two values ​​are printed. Therefore, the randomness of the C language is not random in the true sense. Sometimes it is also called pseudo-random number . Before using rand() to generate random numbers, you need to initialize the pseudo-random number sequence with the initialization function srand(unsigned seed) of the random generator (also located in stdlib.h). Seed is also called random seed. In layman's terms, if you provide it every time If the seeds are the same, the last few random values ​​generated in each round are also the same, so they are called pseudo-random numbers, so we need to provide a different seed each time to achieve complete randomness. We usually use the time function time(NULL) As a seed, because the time value is different every second, this function needs to include the following header files:

#include <time.h>

8. Allocate memory: malloc() and free()

See what the boss said:

9. ANSI C type qualifier

1.const type qualifier
description Example meaning
Const before type const float * p The pointer itself can be changed , and the pointed value cannot be changed
Const before variable name float* const p The pointer itself cannot be changed , and the pointed value can be changed
Type, const before variable name const float* const p The pointer itself cannot be changed , and the pointed value cannot be changed
After type, * before const float const* p The pointer itself can be changed , and the pointed value cannot be changed

    In general: const is placed on the left side of [], the data pointed to by the pointer cannot be changed, placed on the right side of [], the pointer itself cannot be changed

2. Volatile type qualifier

    The volatile qualifier tells the computer that the agent (not the program where the variable is located) can change the value of the variable. Usually, it is used for hardware addresses and sharing data among other programs or threads running at the same time.

(1) The compiler will prohibit read and write optimization of volatile modified variables.

    The volatile keyword is a type modifier. The type variable declared with it can be changed by some factors unknown to the compiler, such as the operating system, hardware, or other threads. When encountering the variable declared by this keyword, the compiler will no longer optimize the code that accesses the variable, so as to provide stable access to the special address.

(2) Every time a volatile modified variable is read, it will be read from the memory.

    Volatile can be interpreted as "direct access to the original memory address"; "variability" is caused by external factors, such as multithreading, interrupts, etc., not because the variable modified with volatile is "volatile", if not External cause, even if volatile definition is used, it will not change.

3.restrict type qualifier

    The restrict keyword allows the compiler to optimize certain parts of the code to better support calculations. It can only be used for pointers, indicating that the pointer is the only and initial way to access the data object.
    Restrict is introduced by the C99 standard. It can only be used to limit and restrict pointers. The object has been referenced by the pointer, and the content of the object cannot be modified by all other direct or indirect methods except the pointer. That is, it tells the compiler that all operations that modify the contents of the memory pointed to by the pointer must be modified through the pointer, and cannot be modified by other means (other variables or pointers); the advantage of this is that it can help the compiler to perform Better optimized code to generate more efficient assembly code. For example, the memory unit pointed to by int *restrict ptr, ptr can only be accessed by ptr, and any other pointers that also point to this memory unit are undefined, straightforward It is an invalid pointer. The emergence of restrict is due to the inherent flaws of the C language. C programmers should actively avoid this flaw, and the compiler will also optimize your code very cooperatively.
    The restrict qualifier can also be used for pointers in function parameters. This means that the compiler can assume that other identifiers in the function body will not modify the data pointed to by the pointer, and the compiler can try to optimize it so that it is not used for other purposes

END——Summary of this chapter:

summary

Guess you like

Origin blog.csdn.net/qq_52355487/article/details/111083201