Advanced use of embedded C language (the most detailed in the whole network)
1, Macro
Macro, in my opinion, is a major feature of C language. On this basis, some special functions can be used.
1.1 variable type parameter macro
In some application scenarios, we often need to find the maximum and minimum values similar to the two. We often encapsulate such a simple function into a method function. However, in the function syntax, we should clearly define the variable types of parameters, that is, different types of variables need to establish relatively different functions, but we use some special means, You can use macros to implement indefinite types of macros with parameters. See the following examples:
#define max(x,y)({\ typeof(x) _x = (x);\ typeof(y) _y = (y);\ (void)(&_x == &_y);\ _x > _y? _x:_y;})
Yes, such a macro with parameters can realize the function of maximizing any variable type.
- First, let's analyze some functions of this code.
typeof: gets the variable type of a variable.
(void) (&_x = = &_y): this code is only used to remind the user whether the two variable types are consistent.
__ x > _ y? _ x:_ y;: Returns the final result.
2, Variable parameters
### 2. 1 simple use of variable parameters
We are actually familiar with variable parameters, but you may not know it yet. Do you remember the first line of code when you first started learning C language? Yes, it is
printf("hallo wolrd!")
In fact, the printf function is implemented using variable parameters. Let's take an example:
printf(char *fmt,...); //This is the prototype of the printf function int count = 10; char sex = 'L'; printf("%d,%c",count,sex);
- fmt: format string.
- . . . : Corresponding to multiple parameters.
To implement variable parameters, you need to add the header file stdarg h
- va_list: actually a char * type.
- va_start(fmt,args): obtain the address after the args parameter according to the address of the parameter args and save it in the fmt pointer variable.
- va_end(args): release the args pointer and assign it NULL.
Let's use a classic and simple example to see the usage.
#include <stdarg.h> void printArray(int count,...) { char var; int gap,i; /*Created a pointer to the parameter*/ va_list args; /*Initialization pointer*/ va_start(args,count); /*The indefinite parameters are analyzed*/ for( i = 0 ; i < count ; i++) { printf("*args %d = %d\n",count,*(int*)args); gap = (int)(sizeof(count)/sizeof(var)); //Gets the number of bytes that the pointer should skip args += gap; } /*The pointer released after use is NULL*/ va_end(args); } void main(void) { printArray(4,1,2,3,4); printArray(5,1,2,3,4,5); }
Finally, we can see that the following parameters are printed one by one
2.2 commissioning
When we write programs, we often need to print some logs. Different things need to be printed under different circumstances, so we often have a debugging module. The following is a simple debugging module program implemented with indefinite parameters, as follows:
#include <stdarg.h> #include <stdio.h> /* Where users need to configure */ #define USER_DEBUG_LEVEL 3 /* ERROR:Error level log WARNIG:Warning level log DEBUG:Log of mode level */ #if USER_DEBUG_LEVEL>=3 #define ERROR #endif #if USER_DEBUG_LEVEL >= 2 #define WARNING #endif #if USER_DEBUG_LEVEL >= 1 #define DEBUG #endif void printfError(char* fmt ,...) { va_list args; va_start(args,fmt); #ifdef ERROR vprintf(fmt,args); #endif va_end(args); } void printfWarning(char* fmt ,...) { va_list args; va_start(args,fmt); #ifdef WARNING vprintf(fmt,args); #endif va_end(args); } void printfDebug(char* fmt ,...) { va_list args; va_start(args,fmt); #ifdef DEBUG vprintf(fmt,args); #endif va_end(args); } void main(void) { printfError("Error\n"); printfWarning("Warning\n"); printfDebug("Debug\n"); }
Different debugging levels correspond to different print data, which can be used for debugging.
3, Inline function
Inline function is to fill the contents of the function body into the place where the function is called after compilation. Instead of calling the function itself, it directly executes the statements in the function body. However, if it is declared as an inline function, it is uncertain whether it is an inline function in the end.
Let's take a simple example, as follows:
inline int sum(int a ,int b) { return a + b; } void main(void) { printf("sum = %d",sum(5,6)); }
The returned result is clear at a glance. In ordinary functions, the sum() function is called and then returned. The inline function fills a+b into the position of the function name as follows, and the action cycle of the formal parameter is in the function statement.
Inline as follows:
inline int sum(int a ,int b) { return a + b; } void main(void) { { int a = 5,b = 6; printf("sum = %d",a + b); } }
Where the function body itself replaces the original function call.
Pay attention to the official account, get the code of this article and some tools in debugging SCM.