This post was last edited by wsdymg on 2018-6-27 08:16
static:
In a function body, a variable declared as static maintains its value while the function is called.
In file scope (but outside the function body), a variable declared as static can be accessed by all functions in the file scope, but cannot be accessed by other functions outside the file scope. It is a local global variable.
In file scope, a function declared as static can only be called by other functions in the file scope. That is, this function is limited to the local scope of the file in which it is declared.
const:Read-only (cannot simply be said as "constant") The purpose of the const keyword is to convey very useful information to people who read your code Using the const keyword can produce more compact code Reasonable use of the const keyword can make the compiler naturally protect parameters that do not want to be changed and prevent them from being modified by unintentional code Examples
const int a; int const a; // a is a constant integer
const int * a; // a is a pointer to a constant integer
int * const a; // a is a constant pointer to an integer
volatile:Prevent compiler optimization A variable defined as volatile means that the variable may be changed unexpectedly. The optimizer must re-read the value of this variable each time it uses it, instead of using the backup stored in the register. Several situations where volatile variables are used:
Hardware registers of I/O interface circuits (such as status registers)
Non-automatic variables accessed in interrupt service routines
Variables shared by several tasks in multitasking
Example
volatile const unsigned char eventI2C;
Declare a read-only unsigned character variable eventI2C const: This program should not attempt to modify it volatile: May be changed by the outside world (hardware, other processes)
// For example, this square function
int square(volatile int *ptr)
{
return (*ptr) * (*ptr); // This may go wrong, because if the value in ptr is modified by an interrupt during the second addressing, the result will be wrong
}
Access absolute address:
// UART register definition in ARM, which can be seen in the header files of many devices
#define ULCON0 (*(volatile unsigned long *)0x01D00000)
#define UCON0 (*(volatile unsigned long *)0x01D00004)
#define UFCON0 (*(volatile unsigned long *)0x01D00008)
#define UMCON0 (*(volatile unsigned long *)0x01D0000C )
#define UTRSTAT0 (*(volatile unsigned long *)0x01D00010)
#define UERSTAT0 (*(volatile unsigned long *)0x01D00014)
#define UFSTAT0 (*(volatile unsigned long *)0x01D00018)
#define UMSTAT0 (*(volatile unsigned long *)0x 01D0001C)
#define UTXH0 (*(volatile unsigned long *)0x01D00020)
#define URXH0 (*(volatile unsigned long *)0x01D00024)
#define UBRDIV0 (*(volatile unsigned long *)0x01D00028)
Infinite loop:
// The first type:
while (1)
{
// This is the most common, that is, the condition is always 1, and the loop does not stop.
}
// The second type:
for (;;)
{
// This is also very common. I think this is easy to understand. It is a true unconditional loop.
}
There is no difference between the compiled results of these two loops now, because many compilers can easily optimize them.