Nineteen, storage type
- Storage type: auto (automatic), static (static), extern (external), register (register)
- Modifiers: const (not allowed to be modified), volatile (prevents memory from being optimized by the compiler)
19.1 auto
Function: declare automatic type, when local variable omits storage type, it is automatic type
- auto cannot modify global variables
- Functions can only be decorated with static / extern, not auto
- The variable memory modified by auto is in the stack area
19.2 static
Function: Declare static type and extend the life cycle.
static
keyword modification:
- Global variable: When
static
is used to modify a global variable, it limits the scope of the variable to the current file, even if other files declare global variables with the same name, they will not affect each other. - Local variable: When
static
is used to modify a local variable, it extends the life cycle of the variable, that is, the variable maintains its value during program execution, rather than being reinitialized every time the function is called. This is especially useful in recursive functions, which cannot be used across scopes. - Pointer:
static
modifying the pointer itself has no special meaning, and its behavior is no different from that of ordinary pointers. However, ifstatic
is used for the variable pointed to by the pointer, then the life cycle of the variable will be extended, similar to the effect of the above local variable. The static modified pointer cannot point to the variable address of the automatic type. - Function: When
static
is used to modify a function, it will limit the scope of the function to the current file, and other files cannot access the function, which has the function of privatization. - Thread-local variables (Thread-local variables):
The C11 standard introduces the concept of thread local variables. By using the static keyword together with the keyword _Thread_local, local variables independent of threads can be created in multi-threaded programs. Each thread has its own independent variable instance, without interfering with each other.
Code sample:
- 1. Static modified global variables
The storage type is omitted for global variables, and the default storage type is extern. The memory space of global variables is in the static area. Generally, global variables will not be decorated with static, because the storage type of global variables is omitted, and the memory is already in the static area.
- 2. Static modification of local variables
Function: static modifies local variables, prolongs life cycle, not scope, Life cycle: the look of the memory space, to release Scope : within the valid scope of the program
- 3. Static modification function
Function: static modification function, so that the function declaration cycle is valid in this file, and cannot be called across files The function omits the storage type, and the default is the extern storage type
- 4. Static modified pointer
The static modified pointer cannot point to the variable address of the automatic type Cause: The variable address of the automatic type is allocated after the address, and the space is allocated at the compilation stage The variable address of the static type is allocated first, and the space is allocated when the project starts
19.3 extern
Role: declare external storage
extern
keyword declaration:
- Global variable: When using
extern
to modify a global variable in a file, it indicates that the variable is a global variable defined in other files. In this way, the global variables defined by other files can be used in the current file, so as to achieve the purpose of sharing global variables among multiple files. - Local variables:
extern
should not be used for local variables, because the scope of local variables is limited to the code block in which it is defined and does not need to be accessed in other files. - Pointer:
extern
can also be used for pointers, but its effect is similar to that of global variables, indicating that the pointer is defined in other files. - Function:
extern
should not be used for functions, because the scope of the function is global, and there is no need to passextern
to access it in other files.
- The current global variable omits the storage type, and the default is extern
- The current global variable omits the storage type, and the default is extern
- Variables modified by extern are stored in the static area
Summary:
static
is mainly used to limit the scope and extend the life cycle.extern
is mainly used to share global variables in multi-file projects.
19.4 register
Function: declare register variables, Variables of register type, the access speed is fast, but the address cannot be taken Memory level: register > cache cache > main memory > auxiliary memory
19.5 const
Function: the modified value does not change 1. The global variables modified by const are stored in the read-only segment of the static area, read-only and cannot be modified 2. Local variables modified by const are stored in the stack area and cannot be modified 3. Combination of const and pointer: \t const int *p; * is on the right side of const, the value modified by const, the value cannot be changed, but the address can be changed int const *p;* is on the right side of const, the value modified by const, the value cannot be changed, but the address can be changed int * const p;* is on the left of const, the address modified by const, the address can be changed, but the value can be changed const int * const p; the first const modification refers to the address of the second const modification, and neither the value nor the address can be changed int const * const p; The first const modification refers to the address of the second const modification, and neither the value nor the address can be changed
19.6 volatile
role: prevent memory optimization, save memory visibility
In C/C++, volatile
is a keyword used to tell the compiler that the variable may be accidentally changed during program execution, thereby preventing the compiler from optimizing the variable to Ensure the correctness of the program. The main use of volatile
is in the following situations:
-
Prevent compiler optimization:
When the compiler optimizes the code, it will minimize the reading and writing of variables to improve the execution efficiency of the program. However, the value of some variables may not be controlled by the current code segment, but changed by hardware or other concurrent threads. Using thevolatile
keyword tells the compiler not to optimize the variable, but to read its latest value from memory every time. -
Related to interrupt handling:
In embedded systems and multithreaded environments, interrupts may modify variables in the program. If these variables are not declared asvolatile
, the compiler may optimize away the read operation of these variables, resulting in program errors. -
Interact with peripherals:
In embedded systems, when interacting with peripherals, using thevolatile
keyword can ensure that access to peripheral registers is not optimized, thereby ensuring correct communication with peripherals.
Please note:volatile
The keyword just tells the compiler that the variable may be modified at any time, but it does not solve all multi-threaded concurrent access problems. For the case of multi-threaded concurrency, more complex synchronization mechanisms (such as mutexes) usually need to be used. In a multi-threaded environment, the volatile
keyword is only a means to ensure that the variable is not optimized, but does not guarantee thread safety.
Twenty, macro
macro: Once defined, it cannot be modified Definition format: #define macro name macro body Macro production replacement, no calculation, no correctness check Macros do not belong to C statements, so do not add semicolons
20.1 Macro definition
#define M 100 #define PAI 3.14 #define CH 'A' #define STRING "hello" #define N #define G =100 // The above are all macros int main(int argc, const char *argv[]) {<!-- --> printf("M=%d\ ",M); printf("PAI=%f\ ",PAI); printf("CH=%c\ ",CH); printf("STRING=%s\ ",STRING); // N=6; //Once the macro definition is not assigned, it cannot be assigned later printf("N=%d\ ",N); // printf("G=%d\ ",M); return 0; }
20.2 Macro function
20.2.1 Custom macro function
Definition format: #define macro function name (parameter list) macro body #define : Define the flag of the macro, which cannot be omitted Macro function name: meet the naming convention, generally capitalized Parameter list: without data type Macro body: the implemented program, without {}
Code sample:
1> Macro function with parentheses #define SUM(x,y) x + y #define SUM1(x,y) (x + y) #define MIN(x,y) x>y?y:x int main(int argc, const char *argv[]) {<!-- --> #if N int a=10,b=100; printf("sum=%d\ ",SUM(a,b)/2);//x + y/2=60 printf("sum=%d\ ",SUM1(a,b)/2);//(10 + 100)/2=55 printf("%d",MIN(a,b)); #endif
20.2.2 System macro function
#if macro name C statement 1; #else C statement 2; #endif When the macro name condition is true, execute C statement 1, otherwise execute C statement 2 #if 0 action comment #ifdef macro name C statement 1; #else C statement 2; #endif When the macro name has been defined, execute C statement 1, otherwise execute that C statement 2 #ifndef macro name C statement 1; #else C statement 2; #endif When the macro name is not defined, execute that C statement 1, otherwise execute that C statement 2; #undef macro name: cancel macro