1. static keywords
To have a deep understanding of the static keyword, you must first master the composition of the Standard C program.
Standard C Programs are always composed of the following parts:
1) body segment-The machine instruction part executed by the CPU, that is, your program. A program has only one copy; read-only, which is used to prevent the program from modifying its own commands due to accidents;
2) initialize the data segment (Data Segment)-store all the global variables assigned with the initial value in the program.
3) Non-initialized data segment (bss segment)-No global variable is initialized in the program; the kernel initializes this segment to 0.
Note: Only global variables are allocated to data segments.
4) Stack-growth direction: top-down growth; automatic variables and information to be saved for each function call (return address and environment information ).
5) Heap-dynamic storage allocation.
Static has three functions in the embedded C language:
Role 1: In the function body, a variable declared as static maintains its value unchanged during the function call process.
Role 2: within a module (but in vitro), a variable declared as static can be accessed by the function used in the module, but not by other functions outside the module. It is a local global variable.
Role 3: In a module, a function declared as static can only be called by other functions in the module. That is, this function is restricted to use within the local scope of the module that declares it.
Auto, register, extern, and static
There are two storage periods: Automatic Storage Period and static storage period.
Auto and register correspond to the automatic storage period. A variable with an automatic storage period is created when it enters the block where the variable is declared. The variable exists during the block activity and is revoked when it exits the block.
The extern and static keywords are used to describe variables and functions with a static storage period.
Local variables declared with static have staticstorage duration or static range (staticextent ). Although its value remains valid between function calls, its name visibility is limited to its local domain. The static local object is initialized for the first time when the program executes the declaration of the object.
2. const keywords
The rational use of the keyword const can enable the compiler to naturally protect those parameters that do not want to be changed, so as to prevent them from being accidentally modified by code.
A. a variable modified by the const keyword can be considered to have a read-only attribute, but it is never equal to a constant. The following code:
Const int I = 5;
Int j = 0;
I = j; // invalid, causing compilation errors because it can only be read
J = I; // valid
B. Variables modified by the const keyword must be initialized during declaration. The following code:
Const int I = 5; // valid
Const intj; // invalid, causing compilation errors
C. Although the variable declared with const increases the allocation space, it can ensure type security. Const was initially derived from C ++ changes. It can replace define to define constants. In c of the old version (before the standard), to create a constant, you must use the Preprocessor:
# Define PI 3.14159
Since then, no matter where PI is used, it will be replaced by a 3.14159 pre-processor. The compiler does not perform a type check on PI, that is, you can create a macro without any restrictions and use it to replace the value. If you use it accidentally, errors may be introduced by preprocessing, which are often hard to find. In addition, we cannot get the PI address (that is, we cannot pass pointers and references to PI ).
The emergence of const has better solved the above problems.
In the d. C Standard, the constant defined by const is global.
E. I have to understand the meaning of the following statement. I remember it for a long time. The method is: to define a read-only attribute pointer, the keyword const should be placed after.
Char * const cp; // the pointer cannot be changed, but the content pointed to can be changed.
Char const * pc1; // the pointer can be changed, but the content to be pointed cannot be changed.
Const char * pc2; // same as above (the last two statements are equivalent)
F. Declare the input parameter of the function as const to indicate that using this parameter is only for the sake of efficiency, rather than for the call function to modify the object value. The const parameter is usually used when the parameter is a pointer or reference, and can only modify the input parameter. If the input parameter adopts the "value transfer" method, because the function will automatically generate a temporary variable for copying this parameter, this parameter does not need to be protected, so it does not need to be modified by const. Example:
Void fun0 (const int * );
Void fun1 (const int & );
When you call a function, use the corresponding variable to initialize the const constant. Then, in the function body, the constant is made according to the Section modified by the const. For example, if the parameter is constint *, you cannot change the content pointed to by the passed pointer to protect the content pointed to by the original pointer. For example, if the parameter is constint & a, you cannot change the passed referenced object, protects the attributes of the original object.
G. Modify the return value of the function to prevent users from modifying the return value. (Usually not used in Embedded C, mainly used in C ++)
H. const eliminates the adverse effects of value substitution of the pre-processor and provides a good type check format and security, using const as much as possible can be of great help to our programming, provided that you have a sufficient understanding of const.
Finally, two common standard C library function declarations are examples of using const.
(1). String Copy function: char * strcpy (char * strDest, const char * strSrc );
(2). Return the string length function: intstrlen (const char * Str );
3. Volatile keywords
A variable defined as volatile means that this variable may be unexpectedly changed, so that the compiler will not assume the value of this variable. Precisely, the optimizer must carefully re-read the value of this variable every time when using this variable, rather than using the backup stored in the register. Since the speed of accessing registers is faster than that of RAM, the compiler generally reduces the access to external Ram.
Generally, volatile is used in the following areas:
(1) Volatile must be added to the variable modified in the interrupt service program for testing by other programs;
(2) Volatile should be added to the labels shared among all tasks in a multi-task environment;
(3) Volatile is also required for memory-mapped hardware registers, because each read/write operation may have different meanings;
The content that does not know volatile will bring about disasters, which is also a key factor in distinguishing C and Embedded C programmers. In order to emphasize the importance of volatile, we will give another example:
Code 1:
Int A, B, C;
// Read the content of port 0 x of the I/O space
A = inword (0x100 );
B =;
A = inword (0x100 );
C =;
Code 2:
Volatile int;
Int A, B, C;
// Read the content of port 0 x of the I/O space
A = inword (0x100 );
B =;
A = inword (0x100)
C =;
In the preceding example, the code is optimized by the vast majority of compilers as follows:
A = inword (0x100)
B =;
C =;
This is obviously not consistent with the goal of the writer. The I/O space 0x100 port may be read out. If volatile is added, as shown in Code 2, the optimizer will not optimize any code. from the above point of view, the volatile keyword will reduce the compiler optimization strength, but it ensures the correctness of the program, so using the keyword volatile in the appropriate place is a test of programming skills.
4. struct and typedef keywords
In the face of a person's large C/C ++ program, we can evaluate the programming experience of the author simply by looking at the usage of struct. Because a large C/C ++ program is bound to involve some (or even a large number) structure for data combination, these structures can combine the original meaning of a whole of data. To some extent, whether or not struct will be used, and how to use struct is a sign that a developer has rich development experience. In the C/C ++ programming of network protocols, communication control, and embedded systems, what we often want to transmit is not a simple byte stream (char array ), it is a combination of multiple types of data, in the form of a struct. Experienced developers often store all the content to be transmitted in a char array in sequence, and transmit network packets and other information through pointer offset. This programming method is complex and error-prone. Once the control mode and communication protocol change, the program must be modified in great detail.
Usage: define a struct type in C using typedef:
Typedef struct student
{
Int;
} Stu;
So when declaring the variable, you can: stustu1;
If there is no typedef, you must use structstudent stu1; to declare that the stu here is actually the alias of structstudent.
In addition, Student can also be left empty here (so it cannot be structStudent stu1)
Typedef struct
{
Int;
Stu;
An important role of the struct keyword is that it can encapsulate data. There are a little bit of objects similar to C ++ that can visualize some scattered features, this provides great convenience when writing complex programs.