The hardest bones in the C language are these three

The hardest bones in the C language are these three

75d82f0462a2559b586af213fcec0658.png

\\ \ Interlude: At the beginning of this year, I recorded a relatively systematic introductory single-chip microcomputer tutorial, and students who want it can find me and take it for free (Hexi - Yanyan - Shand Ge _ _). I have been relatively free recently, and I have completed my project and brought students to participate in competitions // / Green icon【'で】liutianwang123

Start of text: \\\///b0dcbfef11ca81e6b6e1ffd2cb15bee3.png

afb7dd4e22d40b88c3d3a16d55192321.png

C language is a must-have knowledge in embedded learning. Most of the audit operations are carried out around C language, and there are three "hard bones" that are almost recognized.

0x01 pointer

Pointers are recognized as the most difficult concept to understand, and it is also the direct reason why many beginners choose to give up.

The reason why pointers are difficult to understand is because the pointer itself is a variable, a very special variable, a variable dedicated to storing addresses. This address needs to be allocated space to hold things, and because it is a variable that can be assigned intermediate values, so many people are confused. I started to get dizzy and couldn't get around the bend. The reason why C language is liked by many masters is the charm of pointers, which can be flexibly switched in the middle, and the execution efficiency is super high, which is also what makes Xiaobai confused.

Pointers are a point of knowledge that cannot be bypassed by learning, and after learning C language, the next step is to switch to data structures and algorithms. Pointers are the focus of the switch. If the pointers can't figure out the next step, it will be difficult to carry out the next step, which will make many people give up and continue. Courage to learn.

The pointer is directly connected to the memory structure. The common pointer in the C language is pointed randomly, and the root cause of the array out of bounds is the memory problem. There is endless room to play at the point of the pointer. A lot of programming skills are gathered here.

Pointers also involve how to apply for the release of memory. If the release is not timely, memory leaks will occur. Pointers are efficient and easy to use, but not fully understanding it is a nightmare for some people.

For conceptual issues, please refer to the previous tweet "The Most Detailed Explanation of C Language Pointers", then for pointers, you can refer to the experience of the great god:

complex type specification

To understand pointers, there are more or less complex types. So let's first introduce how to fully understand a complex type.

It is actually very simple to understand complex types. There will be many operators in a type. They also have precedence like ordinary expressions, and their precedence is the same as that of operation.

So the author summarizes its principles: starting from the variable name, according to the combination of operator precedence, step by step analysis.

Let's start with a simple type of analysis.

int p;

This is a normal integer variable

int p;

First start from P, first combine with, so that P is a pointer. Then combine with int, indicating that the type of the content pointed to by the pointer is int, so P is a pointer that returns integer data

int p[3];

First start from P, first combine with [], indicating that P is an array. Then combine with int, indicating that the elements in the array are integers, so P is an array composed of integer data.

int *p[3];

First start from P, first combine with [], because its priority ratio is high, so P is an array. Then combined with, indicating that the elements in the array are pointer types. Then it is combined with int to indicate that the type of the content pointed to by the pointer is an integer, so P is an array consisting of pointers that return integer data.

int (*p)[3];

First start from P, first combine with, indicating that P is a pointer. Then it is combined with [] (this step with "()" can be ignored, just to change the priority), indicating that the content pointed to by the pointer is an array. Then combine with int, indicating that the elements in the array are integers. So P is a pointer to 3 integers consisting of integer data.

int **p;

First start with P, first combine with and, indicating that P is a pointer. Then combined with, indicating that the element pointed to by the pointer is a pointer. Then combine with int, indicating that the element pointed to by the pointer is integer data. Since second-level pointers and higher-level pointers are rarely used in complex types, we will not consider multi-level pointers for later more complex types, and only consider first-level pointers at most.

int p(int);

Starting from P, it is first combined with () to indicate that P is a function. Then enter () to analyze, indicating that the function has a parameter of an integer variable, and then combine with the int outside, indicating that the return value of the function is an integer data.

int (*p)(int);

Starting from P, it is first combined with the pointer, indicating that P is a pointer. Then combined with () to indicate that the pointer points to a function. Then it is combined with the int in (), indicating that the function has an int parameter, and then combined with the outermost int, indicating that the return type of the function is an integer, so P is a pointer that has an integer parameter and the return type A pointer to a function of type integer.

int (p(int))[3];

You can skip it first, don't look at this type, it is too complicated. Starting from P, first combine with (), indicating that P is a function. Then enter () inside, combined with int, indicating that the function has an integer variable parameter. Then combined with the outside, indicating that the function returns a pointer. Then go to the outermost layer, first combine with [], indicating that the returned pointer points to an array. Then combine with, indicating that the elements in the array are pointers, and finally combine with int, indicating that the content pointed to by the pointer is integer data. So P is a function that takes an integer as an argument and returns a pointer variable that points to an array of integer pointer variables.

It's almost there. After understanding these types, other types are also side dishes for us. However, generally do not use too complex types, which will greatly reduce the readability of the program, please use with caution. The above types are enough for us.

elaboration pointer

A pointer is a special variable that stores a value that is interpreted as an address in memory.

To figure out a pointer, you need to figure out four aspects of the pointer: the type of the pointer, the type pointed to by the pointer, the value of the pointer or the memory area pointed to by the pointer, and the memory area occupied by the pointer itself. Let us explain separately.

First declare a few pointers for example:

(1)int*ptr;

(2)char*ptr;

(3)int**ptr;

(4)int(*ptr)[3];

(5)int*(*ptr)[4];

type of pointer

From a syntax point of view, friends only need to remove the pointer name in the pointer declaration statement, and the rest is the type of the pointer. This is the type the pointer itself has.

Let's look at the types of each pointer in the above example:

(1) intptr;//The type of the pointer is int

(2) charptr;//The type of the pointer is char

(3) intptr;//The type of the pointer is int

(4) int(ptr)[3];//The type of the pointer is int()[3]

(5) int*(ptr)[4];//The type of the pointer is int(*)[4]

how about it? Isn't there an easy way to find out the type of a pointer?

the type the pointer points to

When accessing the memory area pointed to by a pointer through a pointer, the type pointed to by the pointer determines what the compiler will treat the contents of that memory area as.

From a grammatical point of view, the friends only need to remove the pointer name in the pointer declaration statement and the pointer declarator * to the left of the name, and the rest is the type pointed to by the pointer.

The type pointed to by each pointer in the above example:

(1) intptr; //The type pointed to by the pointer is int

(2) char*ptr; //The type pointed to by the pointer is char*

(3) int*ptr; //The type pointed to by the pointer is int*

(4) int(*ptr)[3]; //The type pointed to by the pointer is int(*)[3]

(5) int*(*ptr)[4]; //The type pointed to by the pointer is int*(*)[4]

In pointer arithmetic, the type pointed to by the pointer plays a big role.

The type of the pointer (that is, the type of the pointer itself) and the type pointed to by the pointer are two concepts. When friends become more and more familiar with C, they will find that the concept of "type" mixed with pointers is divided into two concepts of "type of pointer" and "type pointed to by pointer", which is proficient in pointers. one of the key points.

The author has read a lot of books and found that in some poorly written books, these two concepts of pointers are mixed together, so the books seem inconsistent, and the more I read, the more confused I become.

the value of the pointer

That is, the memory area or address pointed to by the pointer.

The value of a pointer is the value stored by the pointer itself, and this value will be treated by the compiler as an address, not a general value.

In a 32-bit program, the value of all types of pointers is a 32-bit integer, because all memory addresses in a 32-bit program are 32 bits long. The memory area pointed to by the pointer is a memory area whose length is sizeof (the type pointed to by the pointer) starting from the memory address represented by the value of the pointer.

In the future, we say that the value of a pointer is XX, which is equivalent to saying that the pointer points to a memory area with the address as the head of XX; we say that a pointer points to a certain memory area, which is equivalent to saying that the value of the pointer is this The first address of the memory area.

The memory area pointed to by the pointer and the type pointed to by the pointer are two completely different concepts. In Example 1, the type pointed to by the pointer already exists, but since the pointer has not been initialized, the memory area it points to does not exist, or is meaningless.

In the future, whenever you encounter a pointer, you should ask: What is the type of this pointer? What type does the pointer refer to? Where does this pointer point to?

The memory area occupied by the pointer itself

How much memory does the pointer itself take up? Just use the function sizeof (pointer type) to test it. On 32-bit platforms, the pointer itself occupies a length of 4 bytes. The concept of memory occupied by the pointer itself is useful in determining whether a pointer expression is an lvalue.

0x02 function

The basic unit of the process-oriented object module, and corresponding to various combinations, function pointers, pointer functions

A function is a business logic block, the smallest unit of process-oriented and unit modules, and in the execution process of the function, how to exchange data between formal parameters and actual parameters, how to transmit data, and how to design a reasonable function, not only To solve a function, it depends on whether it can be reused to avoid repeated wheel building.

Function pointer and pointer function, the surface is the interchange of two literal meanings. In fact, the meaning is completely different. The pointer function is easier to understand. It is a function that returns a pointer. The function pointer is mainly used in callback functions. Many people think that the function is not returned. Understand, the callback function is even more dizzy. In fact, it can be generally understood that a pointer to a function is itself a pointer variable, but it points to a function during initialization, which returns to the pointer level. It is especially difficult to move the pointer further forward without understanding it.

19a2711a633873aeb9bc0a908d874b4e.png

The developers of the C language did some labor-saving things for the later developers. They wrote a lot of code and completed the common basic functions, which can be used directly by others. But with so many codes, how do you find what you need? It's obviously not realistic to bring all the code.

But these codes have long been classified into different files by early developers, and each piece of code has a unique name. So in fact, learning C language is not that difficult, especially in hands-on exercises and projects. When using the code, just add ( ) after the corresponding name. Such a piece of code is a function. A function can perform a certain function independently and can be used multiple times after it is written once.

Many beginners may confuse functions in C with functions in mathematics. In fact, the truth is not that complicated. The functions in the C language can be traced regularly. As long as you understand the concept, you will find it quite interesting. The English name of the function is  Function, which also means "function" in Chinese. Functions in C language are also closely related to functions.

Let's look at a small piece of C language code:

#include

int main()

{

puts("Hello World");

return 0;

}

Focus on line 4, which prints "Hello World" on the display. As we have said before, puts should be followed by (), and strings should also be placed in ().

In the C language, some statements cannot be used with parentheses, and some statements must be used with parentheses. The parentheses are functions.

C language provides a lot of functions, we only need a simple code to be able to use. However, the bottom layers of these functions are relatively complex, usually a combination of software and hardware, and many details and boundaries have to be considered. If these functions are handed over to programmers to complete, it will greatly increase the learning cost of programmers and reduce the cost of learning. programming efficiency.

With functions, the programming efficiency of C language is like an artifact. Developers only need to call them at any time. Process functions, operation functions, time and date functions, etc. can help us directly realize the functions of C language itself. .

C language functions can be reused.

An obvious feature of a function is that it must be used with parentheses (), and if necessary, the parentheses can also contain data to be processed. For example, puts("Guoguo Junior Brother") uses a piece of code with output function. The name of this code is  puts, and "Shangguan Technology" is the data to be processed by this code. Using functions has a professional name in programming, called function calls.

If the function needs to process multiple data, separate them with commas, for example:

pow(10, 2);

This function is used to find the 2nd power of 10.

Well, see here, do you think that the C language function is actually more interesting, and it is not that complicated and difficult. When you meet a rookie Xiaobai in the future, you may sip a function in C language, and you may be able to attract countless adoring eyes on the spot.

0x03 structure, recursion

Many students who study C language in universities have not finished many courses and have not learned the structure, because from the arrangement of the chapters, it seems that the structure learning is placed in the second half of the textbook, which makes many students feel that the structure It doesn't matter, if it's just to meet the school's exams, or just to get a diploma, it's really not meaningful to study.

If you want to work in the programming industry, you still don’t understand this concept, and you can’t construct a data model. No business entity is completely completed using native data types. When designing data models, many experts usually first The structure data is sorted out. Then design the parameters of the function function, as well as the name, and then actually start to write the C source code.

If the order of the data in the structure is different from the perspective of space saving, the space occupied in the memory is also different, the assignment between the structure and the structure, and the structure has a pointer, then special attention should be paid to the assignment, and deep assignment is required.

Recursion is generally used to count or list some data from scratch. Many beginners feel awkward when using it. How can they call themselves? And when using it, you must set the conditions for jumping out, otherwise it will go on endlessly, and it will really become a wireless infinite loop.

For the knowledge of structure, you can refer to the previous article "The Most Complete Explanation of C Language Structure (struct) (Ten Thousand Words)". For details, you can also refer to the experience of the big guy:

I believe everyone is familiar with structures. Here, I share a summary of my research and study on C language structures. If you find something in this summary that you haven't mastered before, then this article is of some value. Of course, the level is limited, if you find any shortcomings, please point out. The code file test.c I put below. Here, I will analyze and apply C language structures around the following two questions:

What is the role of structs in .C language

.What is the emphasis on memory alignment of structure member variables (emphasis)

For the explanation of some concepts, I will not bring up the definitions on the C language textbook. Let's sit down and talk slowly.

Guess you like

Origin blog.csdn.net/l16756062003/article/details/124902780