Embedded: These three elements of C language should be used well
[Copy link]
As an embedded engineer, how can you write efficient and clear C language programs?
Use C language thinking to construct the program structure
You must have a good foundation in C language algorithms to implement the logical structure of the program
Flexible use of C language pointer operations
Although the above statement seems very abstract and gives people a feeling of falling into a fog, it is actually the process of encountering problems, analyzing problems and solving problems using C language.
When embedded engineers write C language programs, they need to build the program architecture based on the problems they encounter.
For example, we have to deal with the classic problem of "monkeys choosing a king": a group of monkeys, holding hands and forming a circle, start counting from 1 from any monkey. When encountering the number to be eliminated (pre-set), the monkey exits the circle, and the next monkey continues to count from 1, and this cycle repeats. The monkey that is left at the end is the king of the monkeys.
Use C language thinking to build program architecture
The program is divided into three parts:
a. Data acquisition. In order to run the program, the above problem needs to obtain the total number of monkeys, which monkey to start from and the number of monkeys to be eliminated;
b. Data operation requires eliminating corresponding data from a pile of data, and paying attention to the correctness of logic;
c. Improve the running speed of the program, use fewer loops and more pointers.
Logic implementation in C language
a. Data acquisition: parameters are acquired through printf and scanf.
/* Read the problem conditions*/
printf("input total num:");
scanf("%d", &n);
printf("from which num begin:");
scanf("%d", &k);
if (k>n||k==0)
{
printf("please input the right begin num");
return 1;
}
printf("input the out num:");
scanf("%d", &m);
if (m>n||m==0)
{
printf("please input the right del num");
return 2;
}
At the same time, pay attention to the handling of exceptions. For example, the two if statements above are the judgment of abnormal situations. Each abnormal situation corresponds to a different return value, which facilitates the debugging of the program process and the legitimacy of the data.
b. /*Define the linked list node type*/
typedef struct node
{
int data;
struct node *next;
}linklist;
Construct a circular linked list to perform the "monkey" circle construction.
/* Create a circular linked list, the head node also stores information*/
head = (linklist*) malloc(sizeof(linklist));
p = head;
p->data = 1;
p->next = p;
/* Initialize a circular linked list*/
for (i = 2; i <= n; i++)
{
s = (linklist*) malloc(sizeof(linklist));
s->data = i;
s->next = p->next;
p->next = s;
p = p->next;
}
After this step, both head and p(present) become a linked list of "monkey circles". In the process of building this linked list, we need to pay attention to the following points: memory allocation, at this time, follow the principle of allocating as much memory as you use.
If too many are allocated at once, memory leaks will occur, but this small program will not encounter such problems. The second is to be familiar with the construction method of circular linked lists: the tail of the linked list points to the head of the linked list. At this time, if you are careful, you will also think of the situation of a doubly linked list.
c. /* Find the kth node */
p = head;
for (i = 1; i <= k; i++)
{
p = p->next;
}
Find the position from which to start counting. At this point, p points to the starting "monkey". Because the linked list method is used, this process only needs to pay attention to the next pointer of p.
a. Save the initial "monkey" circle parameters.
/*Save the total number of nodes*/
total = n;
printf("\nthe out num:");
q = head;
Why do we keep this? First, we need to control the number of monkeys, so we keep all of them. Secondly, we use q(qurry) to keep the linked list before the monkeys are removed, and connect the linked list after the monkeys are removed. In this way, the elements of the circular linked list are deleted.
b. The monkey counts.
Monkey counting is the key to the entire program, and the following tasks need to be completed: a. Find the starting number of "monkeys"; b. Delete the "monkey"; c. Connect the deleted circular linked list from beginning to end.
/* Stop the loop when there is only one node left*/
while (total != 1)
{
/* Counting process, p points to the node to be deleted*/
for (i = 1; i < m; i++)
{
p = p->next;
}
/* Print the serial number of the node to be deleted*/
printf("[%d] ", p->data);
/* q points to the predecessor of p node*/
while (q->next != p)
{
q = q->next;
}
/* Delete p node*/
q->next = p->next;
/* Save the deleted node pointer*/
s = p;
/* p points to the successor of the deleted node*/
p = p->next;
/* Release the deleted node*/
free(s);
/* The number of nodes is reduced by one*/
total--;
}
/* Print the serial number of the last remaining nodes*/
printf("\n\nthe last num:[%d] \n\n", p->data);
free(p);
}
Through the above data operations, the corresponding linked list elements can be deleted. This may be the charm of C language programs.
Using pointers in C
For example, the definition of the linked list pointers in this program are p, s, and q.
linklist *head, *p, *s, *q;
We know that pointer operations can not only reduce the memory required for data operations, but also increase the running speed of the program.
The advantages of pointers may not be obvious in this program, but they will be very obvious when there is a large amount of data and the requirements for operation speed are sensitive, such as in the Linux kernel.
In short, for embedded engineers, not only can they design good hardware circuits, but if they can also write good software programs, it will make our lives better.
|