Embedded C language programming specification--variables, constants, macros

1. Variables

1. A variable has only one function, and a variable cannot be used for multiple purposes

Note: A variable is only used to represent a specific function, and a variable cannot be used for multiple purposes, that is, when the same variable takes different values, its meanings are also different.
Example: Counter example with two functions
    uint8_t getData(void)
    {
        uint8_t data;
        data = 3;
        data = get(data); /* data has two functions: position and return value of function get */
        return data;
    }
correct Practice: use two variables
    uint8_t getData(void)
    {
        uint8_t num;
         uint8_t data;
        num = 3;
        data = get(data);
        return data;

    }

2. The structure and function are single; do not design a comprehensive data structure;

Explanation: A related set of information is the basis of a structure. The definition of a structure should be able to clearly describe an object, rather than a set of data that is not closely related.

When designing a structure, strive to make the structure represent an abstraction of one real thing, rather than many at the same time. Elements in a structure should represent different aspects of the same transaction, and elements describing different transactions with no or very weak relationships should not be placed in the same structure.

3. Do not use or use global variables less;

Description: Static global variables can be used inside a single file, which can be understood as private member variables of a class.

Global variables should be the private data of the module and cannot be used for external interfaces. Using static type definitions can effectively prevent abnormal access to external files.

4. Prevent local variables from having the same name as global variables;

Note: Although local variables and global variables have different scopes without a syntax error, they are misleading.

5. It is strictly forbidden to use uninitialized variables as rvalues;

Description: Uninitialized errors can be avoided.

6. Construct global variables that only one module or function can modify and create, while other related modules or functions can only access global variables, preventing the phenomenon that multiple different modules or functions can modify and create the same global variable;

7. Initialize variables before first use, the closer the initialization is to the place of use, the better;

Description: Uninitialized variables are a common source of errors in C and C++ programs. Make sure the variable is properly initialized before it is used for the first time. In a better solution, the definition and initialization of variables are intimate.

8. Clarify the initialization order of global variables to avoid cross-module initialization dependencies;

Note: In the system startup phase, before using a global variable, consider when the global variable is initialized, use the global variable and initialize the global variable, and the timing relationship between the two must be clearly analyzed.

9. Minimize unnecessary default conversion and coercion of data types;

Note: When the data type is forced to be converted, the meaning of the data and the value after conversion may change. If these details are not considered carefully, it is likely to leave hidden dangers.

2. Macros, constants

1. When defining expressions with macros, use complete parentheses;

Note: Because the macro is just a simple code replacement, it will not calculate the parameters first, and then pass it like a function.

Example: Macros defined as follows have certain risks

#define RECTANGLE_AREA(a, b) a * b

#define RECTANGLE_AREA(a, b) (a * b)

#define RECTANGLE_AREA(a, b) (a) * (b)

The correct definition should be:

#define RECTANGLE_AREA(a, b) ((a) * (b))

This is because:

If you define #define RECTANGLE_AREA(a, b) a * b or #define RECTANGLE_AREA(a, b) (a * b)

Then c/RECTANGLE_AREA(a, b) will be expanded to c/a * b , c and b should be a division operation, but the result becomes a multiplication operation, causing an error.

If you define #define RECTANGLE_AREA(a, b) (a) * (b)

Then RECTANGLE_AREA(c + d, e + f) will be expanded into: (c + d * e + f), d and e will be operated first, resulting in an error.

2. Put multiple expressions defined by the macro in curly brackets

Explanation: A better way is to write multiple statements as do while(0).
Example: Looking at the following statement, only the first expression of the macro is executed.
    #define FOO(x) \
        printf("arg is %d\n", x); \
        do_something_useful(x);
To illustrate the problem, the writing of the following for statement is slightly inconsistent with the specification
    for (blah = 1; blah < 10; blah++ )
        FOO(blah)
is defined with curly brackets to solve the above problem:
    #define FOO(x) { \
        printf("arg is %s\n", x); \
        do_something_useful(x); \
    }
But if someone Call it like this:
    if (condition == 1)
        FOO(10);
    else
        FOO(20);
then this macro still cannot be used normally, so it must be defined like this to avoid various problems:
    #define FOO(x) do { \
        printf( "arg is %s\n", x); \
        do_something_useful(x); \
       } while(0)

Using do-while(0) to define macros, you don't have to worry about how users use macros, and you don't need to add any constraints to users.

3. When using macros, parameters are not allowed to change;

4. Direct use of devil numbers is not allowed;

5. Unless necessary, functions should be used instead of macros as much as possible;

Note: Compared with functions, macros have some obvious shortcomings: 1. Macros lack type checking, which is not as strict as function call checking; 2. Code written in macro form is difficult to debug and hard to break points, which is not conducive to positioning problems; 3. If macros are called It will cause a waste of code space, which is not as efficient as function space;

6. It is recommended to use const definitions instead of macros for constants;

Note: When an error is reported, only constants will be displayed, and the names of macro definitions will not be displayed. When searching, it is very laborious.

7. Try not to use return, goto, continue, break and other statements that change the program flow in the macro definition;

Note: If these statements that change the process are used in the macro definition, it is easy to cause resource leakage, and it is difficult for the user to notice it.


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324588009&siteId=291194637