Article count:1382 Read by:1966155

Account Entry

Share a few practical tips in embedded C

Latest update time:2022-04-21
    Reads:

Hi everybody, I'm 杂烩君 . This time I will share with you some practical skills in embedded C.

1. Dynamic binding, callback function

The callback function can achieve the role of dynamic binding and reduce the coupling between layers to a certain extent. Regarding the callback function, I have already written an article before: C language, embedded key knowledge: callback function . Maybe many beginners may not understand the callback function. You can use the following figure to understand:

Generally, the order of function calls is that the upper function (caller) calls the lower function (callee). From the above figure, we can see that function 2 of the lower module calls function 3 of the upper module. This calling process is opposite to the general calling process. This process is called callback, and function 3 of the upper module here is the callback function. The callback function is represented by a function pointer.

The C library stdlib.h contains a sorting function: the qsort function. The prototype of this sorting function is:

void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void*));

parameter:

  • base – Pointer to the first element of the array to be sorted.
  • nitems -- the number of elements in the array pointed to by base.
  • size – The size of each element in the array, in bytes.
  • compar – a function used to compare two elements, that is, a function pointer (callback function).
int compar(const void *p1, const void *p2);

If the compare return value is less than 0 (< 0), then the element pointed to by p1 will be sorted to the left of the element pointed to by p2;

If the return value of compar is equal to 0 (= 0), then the order of the element pointed to by p1 and the element pointed to by p2 is uncertain;

If the compare return value is greater than 0 (> 0), then the element pointed to by p1 will be sorted to the right of the element pointed to by p2.

example:

#include <stdio.h>
#include <stdlib.h>

int compar_int(const void *p1, const void *p2)
{
 return (*((int*)p1) - *((int*)p2));
}

void test_qsort(void)
{
 int arr[5] = {85101100};
 
 printf("排序前:");
 for (int i = 0; i < 5; i++)
 {
  printf("%d ", arr[i]);
 }
 
 qsort((int*)arr, 54, compar_int);
 
 printf("\n排序后:");
 for (int i = 0; i < 5; i++)
 {
  printf("%d ", arr[i]);
 }
}

int main(void)
{
 test_qsort();
 return 0;
}

Compilation and running results:

The above is the sharing this time. If there are any errors, please point them out. Thank you. This is the first episode, and we will continue to share more practical programming tips and programming experiences in actual development. Welcome to continue to pay attention. This article only lists some practical tips. It does not mean that they should be used in any scenario. Specific issues need to be analyzed in detail.

2. Use macros to initialize the structure

If you use a structure frequently, it is very convenient to use macros to assign values ​​to the structure.

example:

#include <stdio.h>

#define  NEW_RECT(length, width)  {(length), (width)}

typedef struct _Rect
{

 int length;
 int width;
}Rect;

int main(void)
{
 Rect rect = NEW_RECT(105);
 printf("rect length = %d, width = %d\n", rect.length, rect.width);
 return 0;
}

Compilation and running results:

This method is also seen in the underlying gpio driver of RT-Thread:

3. Structure built-in function pointer

We often construct some structures to store data, and then use these structures in some functions. Next time, you might as well tie the data and the functions that operate on the data together to make it clearer.

Related articles: What are incomplete types?

example:

#include <stdio.h>

#define  NEW_RECT(length, width)  {(calc_area), (length), (width)}

typedef struct _Rect
{

 int (*calc_area)(struct _Rect *pThis);
 int length;
 int width;
}Rect;

int calc_area(struct _Rect *pThis)
{
 return (pThis->length * pThis->width);
}

int main(void)
{
 Rect rect = NEW_RECT(105);
 printf("rect length = %d, width = %d\n", rect.length, rect.width);
 printf("rect area = %d\n", rect.calc_area(&rect));
 return 0;
}

Compilation and running results:

4. Use do{}while(0) to encapsulate macros

#define DBG_PRINTF(fmt, args...)  \
do\
{\
    printf("<<File:%s  Line:%d  Function:%s>> ", __FILE__, __LINE__, __FUNCTION__);\
    printf(fmt, ##args);\
}while(0)

For detailed instructions, please refer to previous articles:

Several very practical macro techniques in C language and embedded

5、void*

It has been introduced before in the first part of C language object programming: encapsulation and abstraction void* . void* In fact, we have come into contact with each other on a daily basis, such as:

void *malloc(size_t size) ;
void *memcpy(void *destin, void *source, unsigned n);
......

void * It is often used to encapsulate functions. Of course, it is also useful in other places, such as defining void* a type of private pointer in a structure to facilitate expansion of the structure. When we usually encapsulate our own functions, we can also consider whether it is necessary to use void* to make the function more versatile.

end



A mouthful of Linux


Follow and reply [ 1024 ] Massive Linux information will be given away

Collection of wonderful articles

Article recommendation

【Album】 ARM
【Album】 Fans Q&A
【Album】 All original works
Album Introduction to linux
Album Computer Network
Album Linux driver


Click " Read the original text " to view more sharing, welcome to share, collect, like, and watch


Latest articles about

 
EEWorld WeChat Subscription

 
EEWorld WeChat Service Number

 
AutoDevelopers

About Us Customer Service Contact Information Datasheet Sitemap LatestNews

Room 1530, Zhongguancun MOOC Times Building,Block B, 18 Zhongguancun Street, Haidian District,Beijing, China Tel:(010)82350740 Postcode:100190

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号