C++ basic syntax (references, inline functions)

Foreword: The knowledge of C++ grammar is complicated, and there are many details to consider. It is not a good way to learn C++ well from the beginning. The content of books is generally more rigorous, but for beginners, many concepts cannot be understood , You may be hit in the head when you come up. Therefore, it is recommended to learn C language well before learning C++, and then listen to the introductory courses. C++ has many grammatical concepts that are a supplement to C language. After learning C language, you can better understand why it is designed in this way. I am also a beginner. This kind of article written is only for summary of notes and analysis and discussion of some concepts, which is convenient for future recall. Due to limited knowledge, mistakes are inevitable. Welcome to read and advise

Table of contents

quote

Referenced Definitions

usage of quotes  

Reference as return value error condition

 The difference between reference and pointer

inline function

Inline function definition

Points to note about inline functions


quote

Referenced Definitions

I don’t know if you are confused by the pointer, especially if you want to change the content of the pointer, you need to pass the secondary pointer to it, and you have to dereference it when using the pointer, and you will be confused when you use it. Sometimes I wonder if it is possible to change the value of the original variable space without passing a pointer in the past? C++ provides us with a function - reference, which may help us solve the above problems

Quoting is actually giving a new name to a variable. Quoting does not open up a new space, it is the same space as the original variable, just like calling you by your pet name and official name, they are both calling you, and you cannot be called you. If you call your nickname by your official name, there will be one more you

When a reference is created, it must have an object, otherwise it cannot be created. This is easy to understand. When there is no such person at all, how can it be given another name? Use the symbol '&' when using a reference. A space can be referenced multiple times, that is, it has multiple aliases

usage of quotes  

1. Reference as a parameter when defining a function

In this way, the effect of using pointers is similar, and the value of the original variable can be changed without passing the pointer

In this way, you are not afraid of being dizzy by the pointer, and it also reduces the space development and improves the efficiency 

Pay attention to the issue of permissions when using references. In reference assignments, powers can be reduced, but not expanded.


int main()
{
	int a = 20;
	int& ta = a;   //权限平移,不变

	const int b = 10;
	int& tb = b;  //这里的tb的权限是高于b的,tb是左值,而b是右值
	                      //tb的权限扩大了。不可以

	const int b = 10;
	const int&  mb = b;  //这样权限就是相等的

	int b = 10;
	const int& nb = b; //这里tb的权限缩小了,这样是可以的

	return 0;
}

2. Reference as the return value of the function

There are prerequisites for reference as a function return value. We all know that a function will open a stack frame when it is created. After the call is completed, the stack frame will be destroyed and the memory will be returned to the operating system. Since the contents of the stack are destroyed , so how to deal with the return value of the function, in fact, after the function call ends, if there is a return value, then before the stack frame is destroyed, a temporary variable will be created to save the final return value

The crux of the problem is that when you return a reference, what you return is just a name. The object pointed to by the reference is in this stack frame. Once the stack frame is destroyed, what is the use of returning a name? This space does not belong to you anymore, just like some people left this world, calling its name, it will never appear again

If you want to return a reference, you must ensure that the referenced object will not disappear after the stack is destroyed, such as global variables in the static area and variables in the heap area, but the advantage is that the efficiency of using a reference as a return value is higher than that of passing a value

Reference as return value error condition

If the life cycle of the referenced object is on the stack, what happens when the reference variable is used again after the stack frame is destroyed?

1. If the destroyed stack frame cannot be cleaned up in the future, it is possible to return the original value

2. The destroyed stack frame has been cleaned up, so the returned value is a random value

3. After the stack frame is destroyed, other stack frames are created, and the data of the destroyed stack frame is overwritten by the data of the newly opened stack frame

int& test(int x, int y)                   
{
	int c = x + y;
	return c;
}


int main()
{
	int& tmp = test(3, 4);

	test(10, 10);//再次调用后,就会将原先栈帧内的数据覆盖掉
	std::cout << tmp << std::endl;
	return 0;
}

 The difference between reference and pointer

1. The opening of a pointer is to open up a separate space, in which the address pointing to the object is stored, while the opening of a reference does not open up a new space separately, but the same space as the original variable

2. The reference must be initialized in the definition, but the pointer is not required

3. After the reference is specified, it cannot be replaced, but the pointer can be replaced

4. The meaning in sizeof() is different, the reference indicates the size of the object, and the size of the pointer is determined by the hardware

5. The pointer access entity needs to be dereferenced, and the reference is implemented by the compiler

6. There are multi-level pointers, but no multi-level references

7. The reference to self-increment means that the referenced entity increases by 1, and the pointer to self-increment means that the pointer is offset by one type of size

inline function

Inline function definition

What is an inline function? Before talking about inline functions, you might as well recall the macro definition functions of C language. We know that the macro functions of C language are replaced in the precompilation stage, which saves the cost of developing functions in the stack, and the running speed is also faster. fast. But, the shortcomings of macro functions are also obvious. First of all, they cannot be debugged, and they are easy to cause ambiguity. A lot of parentheses need to be added. It is not easy to read this kind of code. These shortcomings also show that this is the master's work. Writing method, in order to observe the shortcomings of macro functions more clearly, we write a simple macro function to analyze

#include<stdio.h>

#define Add(x, y)   ((x)*3 + (y))

int main()
{
	int a = 10;
	int b = 20;
	int c = Add(a, b);
	printf("%d ", c);
}

#include<stdio.h>

#define Add(x, y)   ((x)*3 + (y))

int main()
{
    
    //如果不给x加括号, (x*3 + (y)) 其传过去一个表达式,比如Add( 1+5, 10)

	int c = Add(1+5, 10);

    //那么在定义替换时将会是这样 ( 1 + 5 *3 + (10) ) 这就产生了歧义
	
    printf("%d ", c);
    
    


    //如果把最外面的大括号去掉, (x)*3 + (y) 然后调用之后乘以3

    int c = Add(5, 10) *3;
    
    //那么在定义替换时将会是这样 (5) *3 + (10) *3  这就又产生了歧义
	
    printf("%d ", c);
}

From the above example, we can find that any pair of parentheses in the macro function may be reasonable, which makes it difficult to write, look ugly, and cannot be debugged. This advantage, if the macro function can be debugged like a normal function, it would be fine without paying attention to so many details. There really are! The big guys have added the concept of inline function in C++ to solve this kind of problem. Inline function is to add the keyword inline when defining ordinary functions. After adding this keyword, you can continue to write your function. Don’t worry about other things. When the compiler recognizes inline, it will consider optimizing the function you wrote into a macro function. Note: adding inline is just a suggestion for the compiler to optimize it into a macro function, not necessarily. If you The function is very long and complex, itself is not suitable for conversion into a macro, then the compiler can choose to ignore the suggestion

Points to note about inline functions

Therefore, inline functions are suitable for short and concise functions, and effective use will improve efficiency. In fact, if you call an inline function frequently, then the inline function may be exchanging space for time . What does that mean? Let's take a look at the example just now

#include<iostream>

using namespace std;

inline int Add(int x, int y)
{
     return x+y; 
)

int add(int x, int y)
{
   return x+y;
}

int main()
{
	int c = Add(10, 10);
    int d = Add(10, 10);
    int e = Add(10, 10);
    int f = Add(10, 10);
    int g = Add(10, 10);
    int h = Add(10, 10);
    int i = Add(10, 10);
    int j = Add(10, 10);
    int k = Add(10, 10);
}

Use inline functions and ordinary functions to add two numbers, because inline functions will optimize them into macro functions, and they will all be expanded to the place where the function is called when compiling. Our writing is relatively simple, assuming that there are 10 statements in Add and add, and the two functions are called 10,000 times at the same time, then when the inline function is expanded, there are a total of 1w * 10 statements, while the ordinary function has 1w + 10 statements, obviously the code of the inline function takes up more space, but its speed is still very fast

The declaration and definition of an inline function cannot be separated . What does that mean? We usually like to put the declaration of the function in the header file, and then put the implementation of the function in another header file, but for the inline function, it is not possible to separate it in this way. The declaration and definition must be put together. Why? ?

Originally you declare a function in test_a.h, define the declared function in test_b.c, and call this function in test_c.c, but these three files are independent, and they don’t know each other. What happened in the end? What about finding the function definition when calling it?

Remember what we mentioned before that in the compilation phase of C/C++, each file will be analyzed lexically and syntactically when compiling, and the defined symbols will be extracted to generate a symbol table, and the function name or address of the function will be placed in the On this symbol table, for example, there are only function declarations in test_a.h, but no function definitions. The generated symbol table is invalid at the function address, but it will be linked later, and the generated multiple symbol tables After merging, the valid function name and valid function address will be retained after merging, and the definition and declaration of the function can be found through the final symbol table

General functions are compiled according to the above method, but macro functions are different, because macro functions are replaced in the pre-compilation stage, which is equivalent to directly expanding the code of the function to the calling place, without opening a stack in the stack area Frame, no function address is required, so the function name of the macro function will not be placed in the symbol table, and the purpose of the inline function is to suggest that the function be converted into a macro function, so, no matter whether the function is eventually replaced by a macro , As long as you add inline it will not appear in the symbol table

Suppose you declare an inline function inline int Add(int x, int y) in test_a.h, define   inline int Add(int x, int y) in test_b.c, and then call  Add(10 , 10 ), at this time the compiler will report an undefined error

Because the inline function will not enter the symbol table, and the main function only contains the declaration file "C++test.h", that is to say, the main function will look up this function in the symbol table through the declaration of this function, of course It can’t be reached, so an undefined error is reported. If we directly include the "C++test.cpp" function, it will be able to run, because the content of "C++test.cpp" will be directly expanded to main. In the file, so when defining an inline function, do not separate the definition and declaration, they need to be written together

Guess you like

Origin blog.csdn.net/m0_61350245/article/details/126975191